Merge "aconfig: comment out new storage invocations" into main
diff --git a/core/Makefile b/core/Makefile
index 9d77ec1..b245d32 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -1469,8 +1469,13 @@
 boototapackage_4k: $(BUILT_BOOT_OTA_PACKAGE_4K)
 .PHONY: boototapackage_4k
 
+ifeq ($(BOARD_16K_OTA_MOVE_VENDOR),true)
+$(eval $(call copy-one-file,$(BUILT_BOOT_OTA_PACKAGE_4K),$(TARGET_OUT_VENDOR)/boot_otas/boot_ota_4k.zip))
+$(eval $(call copy-one-file,$(BUILT_BOOT_OTA_PACKAGE_16K),$(TARGET_OUT_VENDOR)/boot_otas/boot_ota_16k.zip))
+else
 $(eval $(call copy-one-file,$(BUILT_BOOT_OTA_PACKAGE_4K),$(TARGET_OUT)/boot_otas/boot_ota_4k.zip))
 $(eval $(call copy-one-file,$(BUILT_BOOT_OTA_PACKAGE_16K),$(TARGET_OUT)/boot_otas/boot_ota_16k.zip))
+endif # BOARD_16K_OTA_MOVE_VENDOR == true
 
 ALL_DEFAULT_INSTALLED_MODULES += $(TARGET_OUT)/boot_otas/boot_ota_4k.zip
 ALL_DEFAULT_INSTALLED_MODULES += $(TARGET_OUT)/boot_otas/boot_ota_16k.zip
diff --git a/core/OWNERS b/core/OWNERS
index 1c3d017..35ea83d 100644
--- a/core/OWNERS
+++ b/core/OWNERS
@@ -11,5 +11,3 @@
 # For Ravenwood test configs
 per-file ravenwood_test_config_template.xml = jsharkey@google.com,omakoto@google.com
 
-# For binary_translation
-per-file berberis_test.mk = levarum@google.com,khim@google.com,dimitry@google.com
diff --git a/core/android_soong_config_vars.mk b/core/android_soong_config_vars.mk
index 0176574..a71c6f2 100644
--- a/core/android_soong_config_vars.mk
+++ b/core/android_soong_config_vars.mk
@@ -44,49 +44,6 @@
   BRANCH_DEFAULT_MODULE_BUILD_FROM_SOURCE := false
 endif
 
-ifneq ($(SANITIZE_TARGET)$(EMMA_INSTRUMENT_FRAMEWORK),)
-  # Always use sources when building the framework with Java coverage or
-  # sanitized builds as they both require purpose built prebuilts which we do
-  # not provide.
-  BRANCH_DEFAULT_MODULE_BUILD_FROM_SOURCE := true
-endif
-
-ifneq ($(CLANG_COVERAGE)$(NATIVE_COVERAGE_PATHS),)
-  # Always use sources when building with clang coverage and native coverage.
-  # It is possible that there are certain situations when building with coverage
-  # would work with prebuilts, e.g. when the coverage is not being applied to
-  # modules for which we provide prebuilts. Unfortunately, determining that
-  # would require embedding knowledge of which coverage paths affect which
-  # modules here. That would duplicate a lot of information, add yet another
-  # location  module authors have to update and complicate the logic here.
-  # For nowe we will just always build from sources when doing coverage builds.
-  BRANCH_DEFAULT_MODULE_BUILD_FROM_SOURCE := true
-endif
-
-# ART does not provide linux_bionic variants needed for products that
-# set HOST_CROSS_OS=linux_bionic.
-ifeq (linux_bionic,${HOST_CROSS_OS})
-  BRANCH_DEFAULT_MODULE_BUILD_FROM_SOURCE := true
-endif
-
-# ART does not provide host side arm64 variants needed for products that
-# set HOST_CROSS_ARCH=arm64.
-ifeq (arm64,${HOST_CROSS_ARCH})
-  BRANCH_DEFAULT_MODULE_BUILD_FROM_SOURCE := true
-endif
-
-# TV based devices do not seem to work with prebuilts, so build from source
-# for now and fix in a follow up.
-ifneq (,$(filter tv,$(subst $(comma),$(space),${PRODUCT_CHARACTERISTICS})))
-  BRANCH_DEFAULT_MODULE_BUILD_FROM_SOURCE := true
-endif
-
-# ATV based devices do not seem to work with prebuilts, so build from source
-# for now and fix in a follow up.
-ifneq (,${PRODUCT_IS_ATV})
-  BRANCH_DEFAULT_MODULE_BUILD_FROM_SOURCE := true
-endif
-
 ifneq (,$(MODULE_BUILD_FROM_SOURCE))
   # Keep an explicit setting.
 else ifeq (,$(filter docs sdk win_sdk sdk_addon,$(MAKECMDGOALS))$(findstring com.google.android.conscrypt,$(PRODUCT_PACKAGES))$(findstring com.google.android.go.conscrypt,$(PRODUCT_PACKAGES)))
diff --git a/core/envsetup.mk b/core/envsetup.mk
index 7f9cbad..1c3a1b3 100644
--- a/core/envsetup.mk
+++ b/core/envsetup.mk
@@ -57,18 +57,6 @@
   KEEP_VNDK ?= true
 endif
 
-ifeq ($(KEEP_VNDK),true)
-  # Starting in Android U, non-VNDK devices not supported
-  # WARNING: DO NOT CHANGE: if you are downstream of AOSP, and you change this, without
-  # letting upstream know it's important to you, we may do cleanup which breaks this
-  # significantly. Please let us know if you are changing this.
-  ifndef BOARD_VNDK_VERSION
-  # READ WARNING - DO NOT CHANGE
-  BOARD_VNDK_VERSION := current
-  # READ WARNING - DO NOT CHANGE
-  endif
-endif
-
 # ---------------------------------------------------------------
 # Set up version information
 include $(BUILD_SYSTEM)/version_util.mk
diff --git a/core/main.mk b/core/main.mk
index bc8adde..b798b49 100644
--- a/core/main.mk
+++ b/core/main.mk
@@ -1222,8 +1222,7 @@
 # Returns modules included automatically as a result of certain BoardConfig
 # variables being set.
 define auto-included-modules
-  $(if $(and $(BOARD_VNDK_VERSION),$(filter true,$(KEEP_VNDK))),vndk_package) \
-  $(if $(filter true,$(KEEP_VNDK)),,llndk_in_system) \
+  llndk_in_system \
   $(if $(DEVICE_MANIFEST_FILE),vendor_manifest.xml) \
   $(if $(DEVICE_MANIFEST_SKUS),$(foreach sku, $(DEVICE_MANIFEST_SKUS),vendor_manifest_$(sku).xml)) \
   $(if $(ODM_MANIFEST_FILES),odm_manifest.xml) \
diff --git a/core/product.mk b/core/product.mk
index aa9a9a3..9752f32 100644
--- a/core/product.mk
+++ b/core/product.mk
@@ -325,6 +325,13 @@
 # set this variable to prevent OTA failures.
 _product_list_vars += PRODUCT_OTA_ENFORCE_VINTF_KERNEL_REQUIREMENTS
 
+# If set to true, this product forces HIDL to be enabled by declaring android.hidl.manager
+# and android.hidl.token in the framework manifest. The product will also need to add the
+# 'hwservicemanager' service to PRODUCT_PACKAGES if its SHIPPING_API_LEVEL is greater than 34.
+# This should only be used during bringup for devices that are targeting FCM 202404 and still
+# have partner-owned HIDL interfaces that are being converted to AIDL.
+_product_single_value_vars += PRODUCT_HIDL_ENABLED
+
 # If set to true, this product builds a generic OTA package, which installs generic system images
 # onto matching devices. The product may only build a subset of system images (e.g. only
 # system.img), so devices need to install the package in a system-only OTA manner.
diff --git a/core/product_config.mk b/core/product_config.mk
index d16c38d..4eeac95 100644
--- a/core/product_config.mk
+++ b/core/product_config.mk
@@ -630,6 +630,15 @@
 endif
 endef
 
+ifndef PRODUCT_VIRTUAL_AB_COW_VERSION
+  PRODUCT_VIRTUAL_AB_COW_VERSION := 2
+  ifdef PRODUCT_SHIPPING_API_LEVEL
+    ifeq (true,$(call math_gt_or_eq,$(PRODUCT_SHIPPING_API_LEVEL),34))
+      PRODUCT_VIRTUAL_AB_COW_VERSION := 3
+    endif
+  endif
+endif
+
 # Copy and check the value of each PRODUCT_BUILD_*_IMAGE variable
 $(foreach image, \
     PVMFW \
diff --git a/core/soong_config.mk b/core/soong_config.mk
index e382407..3cffef2 100644
--- a/core/soong_config.mk
+++ b/core/soong_config.mk
@@ -152,10 +152,6 @@
 $(call add_json_str,  BtConfigIncludeDir,                $(BOARD_BLUETOOTH_BDROID_BUILDCFG_INCLUDE_DIR))
 $(call add_json_list, DeviceKernelHeaders,               $(TARGET_DEVICE_KERNEL_HEADERS) $(TARGET_BOARD_KERNEL_HEADERS) $(TARGET_PRODUCT_KERNEL_HEADERS))
 $(call add_json_str,  VendorApiLevel,                    $(BOARD_API_LEVEL))
-ifeq ($(KEEP_VNDK),true)
-$(call add_json_str,  DeviceVndkVersion,                 $(BOARD_VNDK_VERSION))
-$(call add_json_str,  Platform_vndk_version,             $(PLATFORM_VNDK_VERSION))
-endif
 $(call add_json_list, ExtraVndkVersions,                 $(PRODUCT_EXTRA_VNDK_VERSIONS))
 $(call add_json_list, DeviceSystemSdkVersions,           $(BOARD_SYSTEMSDK_VERSIONS))
 $(call add_json_str,  RecoverySnapshotVersion,           $(RECOVERY_SNAPSHOT_VERSION))
diff --git a/core/tasks/automotive-sdv-tests.mk b/core/tasks/automotive-sdv-tests.mk
new file mode 100644
index 0000000..12706ce
--- /dev/null
+++ b/core/tasks/automotive-sdv-tests.mk
@@ -0,0 +1,61 @@
+# Copyright (C) 2022 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: automotive-sdv-tests
+
+automotive-sdv-tests-zip := $(PRODUCT_OUT)/automotive-sdv-tests.zip
+# Create an artifact to include a list of test config files in automotive-sdv-tests.
+automotive-sdv-tests-list-zip := $(PRODUCT_OUT)/automotive-sdv-tests_list.zip
+# Create an artifact to include all test config files in automotive-sdv-tests.
+automotive-sdv-tests-configs-zip := $(PRODUCT_OUT)/automotive-sdv-tests_configs.zip
+my_host_shared_lib_for_automotive_sdv_tests := $(call copy-many-files,$(COMPATIBILITY.automotive-sdv-tests.HOST_SHARED_LIBRARY.FILES))
+automotive_sdv_tests_host_shared_libs_zip := $(PRODUCT_OUT)/automotive-sdv-tests_host-shared-libs.zip
+
+$(automotive-sdv-tests-zip) : .KATI_IMPLICIT_OUTPUTS := $(automotive-sdv-tests-list-zip) $(automotive-sdv-tests-configs-zip) $(automotive_sdv_tests_host_shared_libs_zip)
+$(automotive-sdv-tests-zip) : PRIVATE_automotive_sdv_tests_list := $(PRODUCT_OUT)/automotive-sdv-tests_list
+$(automotive-sdv-tests-zip) : PRIVATE_HOST_SHARED_LIBS := $(my_host_shared_lib_for_automotive_sdv_tests)
+$(automotive-sdv-tests-zip) : PRIVATE_automotive_host_shared_libs_zip := $(automotive_sdv_tests_host_shared_libs_zip)
+$(automotive-sdv-tests-zip) : $(COMPATIBILITY.automotive-sdv-tests.FILES) $(my_host_shared_lib_for_automotive_sdv_tests) $(SOONG_ZIP)
+	rm -f $@-shared-libs.list
+	echo $(sort $(COMPATIBILITY.automotive-sdv-tests.FILES)) | tr " " "\n" > $@.list
+	grep $(HOST_OUT_TESTCASES) $@.list > $@-host.list || true
+	grep -e .*\\.config$$ $@-host.list > $@-host-test-configs.list || true
+	$(hide) for shared_lib in $(PRIVATE_HOST_SHARED_LIBS); do \
+	  echo $$shared_lib >> $@-host.list; \
+	  echo $$shared_lib >> $@-shared-libs.list; \
+	done
+	grep $(HOST_OUT_TESTCASES) $@-shared-libs.list > $@-host-shared-libs.list || true
+	grep $(TARGET_OUT_TESTCASES) $@.list > $@-target.list || true
+	grep -e .*\\.config$$ $@-target.list > $@-target-test-configs.list || true
+	$(hide) $(SOONG_ZIP) -d -o $@ -P host -C $(HOST_OUT) -l $@-host.list -P target -C $(PRODUCT_OUT) -l $@-target.list
+	$(hide) $(SOONG_ZIP) -d -o $(automotive-sdv-tests-configs-zip) \
+	  -P host -C $(HOST_OUT) -l $@-host-test-configs.list \
+	  -P target -C $(PRODUCT_OUT) -l $@-target-test-configs.list
+	$(SOONG_ZIP) -d -o $(PRIVATE_automotive_host_shared_libs_zip) \
+	  -P host -C $(HOST_OUT) -l $@-host-shared-libs.list
+	rm -f $(PRIVATE_automotive_sdv_tests_list)
+	$(hide) grep -e .*\\.config$$ $@-host.list | sed s%$(HOST_OUT)%host%g > $(PRIVATE_automotive_sdv_tests_list)
+	$(hide) grep -e .*\\.config$$ $@-target.list | sed s%$(PRODUCT_OUT)%target%g >> $(PRIVATE_automotive_sdv_tests_list)
+	$(hide) $(SOONG_ZIP) -d -o $(automotive-sdv-tests-list-zip) -C $(dir $@) -f $(PRIVATE_automotive_sdv_tests_list)
+	rm -f $@.list $@-host.list $@-target.list $@-host-test-configs.list $@-target-test-configs.list \
+	  $@-shared-libs.list $@-host-shared-libs.list $(PRIVATE_automotive_sdv_tests_list)
+
+automotive-sdv-tests: $(automotive-sdv-tests-zip)
+$(call dist-for-goals, automotive-sdv-tests, $(automotive-sdv-tests-zip) $(automotive-sdv-tests-list-zip) $(automotive-sdv-tests-configs-zip) $(automotive_sdv_tests_host_shared_libs_zip))
+
+$(call declare-1p-container,$(automotive-sdv-tests-zip),)
+$(call declare-container-license-deps,$(automotive-sdv-tests-zip),$(COMPATIBILITY.automotive-sdv-tests.FILES) $(my_host_shared_lib_for_automotive_sdv_tests),$(PRODUCT_OUT)/:/)
+
+tests: automotive-sdv-tests
diff --git a/target/board/BoardConfigMainlineCommon.mk b/target/board/BoardConfigMainlineCommon.mk
index 2b17349..b5e3dc2 100644
--- a/target/board/BoardConfigMainlineCommon.mk
+++ b/target/board/BoardConfigMainlineCommon.mk
@@ -24,11 +24,6 @@
 # the devices with metadata parition
 BOARD_USES_METADATA_PARTITION := true
 
-ifeq ($(KEEP_VNDK),true)
-# Default is current, but allow devices to override vndk version if needed.
-BOARD_VNDK_VERSION ?= current
-endif
-
 # 64 bit mediadrmserver
 TARGET_ENABLE_MEDIADRM_64 := true
 
diff --git a/target/product/gsi/Android.mk b/target/product/gsi/Android.mk
index 3bb65ac..fc6cc68 100644
--- a/target/product/gsi/Android.mk
+++ b/target/product/gsi/Android.mk
@@ -1,95 +1,18 @@
 LOCAL_PATH:= $(call my-dir)
 
 #####################################################################
-# list of vndk libraries from the source code.
-INTERNAL_VNDK_LIB_LIST := $(SOONG_VNDK_LIBRARIES_FILE)
-
-#####################################################################
 # Check the generate list against the latest list stored in the
 # source tree
-.PHONY: check-vndk-list
+.PHONY: check-abi-dump-list
 
 # Check if vndk list is changed
-droidcore: check-vndk-list
+droidcore: check-abi-dump-list
 
-check-vndk-list-timestamp := $(call intermediates-dir-for,PACKAGING,vndk)/check-list-timestamp
 check-vndk-abi-dump-list-timestamp := $(call intermediates-dir-for,PACKAGING,vndk)/check-abi-dump-list-timestamp
 
-ifeq ($(TARGET_IS_64_BIT)|$(TARGET_2ND_ARCH),true|)
-# TODO(b/110429754) remove this condition when we support 64-bit-only device
-check-vndk-list: ;
-else ifeq ($(TARGET_SKIP_CURRENT_VNDK),true)
-check-vndk-list: ;
-else ifeq ($(BOARD_VNDK_VERSION),)
-check-vndk-list: ;
-else
-check-vndk-list: $(check-vndk-list-timestamp)
 ifneq ($(SKIP_ABI_CHECKS),true)
-check-vndk-list: $(check-vndk-abi-dump-list-timestamp)
+check-abi-dump-list: $(check-abi-dump-list-timestamp)
 endif
-endif
-
-_vndk_check_failure_message := " error: VNDK library list has been changed.\n"
-ifeq (REL,$(PLATFORM_VERSION_CODENAME))
-_vndk_check_failure_message += "       Changing the VNDK library list is not allowed in API locked branches."
-else
-_vndk_check_failure_message += "       Run \`update-vndk-list.sh\` to update $(LATEST_VNDK_LIB_LIST)"
-endif
-
-# The *-ndk_platform.so libraries no longer exist and are removed from the VNDK set. However, they
-# can exist if NEED_AIDL_NDK_PLATFORM_BACKEND is set to true for legacy devices. Don't be bothered
-# with the extraneous libraries.
-ifeq ($(NEED_AIDL_NDK_PLATFORM_BACKEND),true)
-	_READ_INTERNAL_VNDK_LIB_LIST := sed /ndk_platform.so/d $(INTERNAL_VNDK_LIB_LIST)
-else
-	_READ_INTERNAL_VNDK_LIB_LIST := cat $(INTERNAL_VNDK_LIB_LIST)
-endif
-
-$(check-vndk-list-timestamp): $(INTERNAL_VNDK_LIB_LIST) $(LATEST_VNDK_LIB_LIST) $(HOST_OUT_EXECUTABLES)/update-vndk-list.sh
-	$(hide) ($(_READ_INTERNAL_VNDK_LIB_LIST) | sort | \
-	diff --old-line-format="Removed %L" \
-	  --new-line-format="Added %L" \
-	  --unchanged-line-format="" \
-	  <(cat $(LATEST_VNDK_LIB_LIST) | sort) - \
-	  || ( echo -e $(_vndk_check_failure_message); exit 1 ))
-	$(hide) mkdir -p $(dir $@)
-	$(hide) touch $@
-
-#####################################################################
-# Script to update the latest VNDK lib list
-include $(CLEAR_VARS)
-LOCAL_MODULE := update-vndk-list.sh
-LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
-LOCAL_LICENSE_CONDITIONS := notice
-LOCAL_NOTICE_FILE := build/soong/licenses/LICENSE
-LOCAL_MODULE_CLASS := EXECUTABLES
-LOCAL_MODULE_STEM := $(LOCAL_MODULE)
-LOCAL_IS_HOST_MODULE := true
-include $(BUILD_SYSTEM)/base_rules.mk
-$(LOCAL_BUILT_MODULE): PRIVATE_INTERNAL_VNDK_LIB_LIST := $(INTERNAL_VNDK_LIB_LIST)
-$(LOCAL_BUILT_MODULE): PRIVATE_LATEST_VNDK_LIB_LIST := $(LATEST_VNDK_LIB_LIST)
-$(LOCAL_BUILT_MODULE):
-	@echo "Generate: $@"
-	@mkdir -p $(dir $@)
-	@rm -f $@
-	$(hide) echo "#!/bin/bash" > $@
-ifeq (REL,$(PLATFORM_VERSION_CODENAME))
-	$(hide) echo "echo Updating VNDK library list is NOT allowed in API locked branches." >> $@; \
-	        echo "exit 1" >> $@
-else
-	$(hide) echo "if [ -z \"\$${ANDROID_BUILD_TOP}\" ]; then" >> $@; \
-	        echo "  echo Run lunch or choosecombo first" >> $@; \
-	        echo "  exit 1" >> $@; \
-	        echo "fi" >> $@; \
-	        echo "cd \$${ANDROID_BUILD_TOP}" >> $@
-ifeq ($(NEED_AIDL_NDK_PLATFORM_BACKEND),true)
-	$(hide) echo "sed /ndk_platform.so/d $(PRIVATE_INTERNAL_VNDK_LIB_LIST) > $(PRIVATE_LATEST_VNDK_LIB_LIST)" >> $@
-else
-	$(hide) echo "cp $(PRIVATE_INTERNAL_VNDK_LIB_LIST) $(PRIVATE_LATEST_VNDK_LIB_LIST)" >> $@
-endif
-	$(hide) echo "echo $(PRIVATE_LATEST_VNDK_LIB_LIST) updated." >> $@
-endif
-	@chmod a+x $@
 
 #####################################################################
 # ABI reference dumps.
@@ -142,15 +65,13 @@
 $(notdir $(call filter-abi-dump-paths,$(1),$(2)))
 endef
 
-
+VNDK_ABI_DUMP_DIR := prebuilts/abi-dumps/vndk/$(RELEASE_BOARD_API_LEVEL)
 ifeq (REL,$(PLATFORM_VERSION_CODENAME))
-    NDK_ABI_DUMP_DIR := prebuilts/abi-dumps/ndk/$(PLATFORM_SDK_VERSION)
     PLATFORM_ABI_DUMP_DIR := prebuilts/abi-dumps/platform/$(PLATFORM_SDK_VERSION)
 else
-    NDK_ABI_DUMP_DIR := prebuilts/abi-dumps/ndk/current
     PLATFORM_ABI_DUMP_DIR := prebuilts/abi-dumps/platform/current
 endif
-NDK_ABI_DUMPS := $(call find-abi-dump-paths,$(NDK_ABI_DUMP_DIR))
+VNDK_ABI_DUMPS := $(call find-abi-dump-paths,$(VNDK_ABI_DUMP_DIR))
 PLATFORM_ABI_DUMPS := $(call find-abi-dump-paths,$(PLATFORM_ABI_DUMP_DIR))
 
 # Check for superfluous lsdump files. Since LSDUMP_PATHS only covers the
@@ -158,22 +79,15 @@
 # Mainline modules may be in use, we also allow the libs in STUB_LIBRARIES for
 # NDK and platform ABIs.
 
-$(check-vndk-abi-dump-list-timestamp): PRIVATE_LSDUMP_PATHS := $(LSDUMP_PATHS)
-$(check-vndk-abi-dump-list-timestamp): PRIVATE_STUB_LIBRARIES := $(STUB_LIBRARIES)
-$(check-vndk-abi-dump-list-timestamp):
+$(check-abi-dump-list-timestamp): PRIVATE_LSDUMP_PATHS := $(LSDUMP_PATHS)
+$(check-abi-dump-list-timestamp): PRIVATE_STUB_LIBRARIES := $(STUB_LIBRARIES)
+$(check-abi-dump-list-timestamp):
 	$(eval added_vndk_abi_dumps := $(strip $(sort $(filter-out \
-	  $(call filter-abi-dump-names,LLNDK VNDK-SP VNDK-core,$(PRIVATE_LSDUMP_PATHS)), \
+	  $(call filter-abi-dump-names,LLNDK,$(PRIVATE_LSDUMP_PATHS)), \
 	  $(notdir $(VNDK_ABI_DUMPS))))))
 	$(if $(added_vndk_abi_dumps), \
 	  echo -e "Found unexpected ABI reference dump files under $(VNDK_ABI_DUMP_DIR). It is caused by mismatch between Android.bp and the dump files. Run \`find \$${ANDROID_BUILD_TOP}/$(VNDK_ABI_DUMP_DIR) '(' -name $(subst $(space), -or -name ,$(added_vndk_abi_dumps)) ')' -delete\` to delete the dump files.")
 
-	$(eval added_ndk_abi_dumps := $(strip $(sort $(filter-out \
-	  $(call filter-abi-dump-names,NDK,$(PRIVATE_LSDUMP_PATHS)) \
-	  $(addsuffix .lsdump,$(PRIVATE_STUB_LIBRARIES)), \
-	  $(notdir $(NDK_ABI_DUMPS))))))
-	$(if $(added_ndk_abi_dumps), \
-	  echo -e "Found unexpected ABI reference dump files under $(NDK_ABI_DUMP_DIR). It is caused by mismatch between Android.bp and the dump files. Run \`find \$${ANDROID_BUILD_TOP}/$(NDK_ABI_DUMP_DIR) '(' -name $(subst $(space), -or -name ,$(added_ndk_abi_dumps)) ')' -delete\` to delete the dump files.")
-
 	# TODO(b/314010764): Remove LLNDK tag after PLATFORM_SDK_VERSION is upgraded to 35.
 	$(eval added_platform_abi_dumps := $(strip $(sort $(filter-out \
 	  $(call filter-abi-dump-names,LLNDK PLATFORM,$(PRIVATE_LSDUMP_PATHS)) \
@@ -182,7 +96,7 @@
 	$(if $(added_platform_abi_dumps), \
 	  echo -e "Found unexpected ABI reference dump files under $(PLATFORM_ABI_DUMP_DIR). It is caused by mismatch between Android.bp and the dump files. Run \`find \$${ANDROID_BUILD_TOP}/$(PLATFORM_ABI_DUMP_DIR) '(' -name $(subst $(space), -or -name ,$(added_platform_abi_dumps)) ')' -delete\` to delete the dump files.")
 
-	$(if $(added_vndk_abi_dumps)$(added_ndk_abi_dumps)$(added_platform_abi_dumps),exit 1)
+	$(if $(added_vndk_abi_dumps)$(added_platform_abi_dumps),exit 1)
 	$(hide) mkdir -p $(dir $@)
 	$(hide) touch $@
 
@@ -190,27 +104,6 @@
 # VNDK package and snapshot.
 
 include $(CLEAR_VARS)
-LOCAL_MODULE := vndk_package
-LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
-LOCAL_LICENSE_CONDITIONS := notice
-LOCAL_NOTICE_FILE := build/soong/licenses/LICENSE
-# Filter LLNDK libs moved to APEX to avoid pulling them into /system/LIB
-LOCAL_REQUIRED_MODULES := llndk_in_system
-
-ifneq ($(TARGET_SKIP_CURRENT_VNDK),true)
-LOCAL_REQUIRED_MODULES += \
-    vndkcorevariant.libraries.txt \
-    $(addsuffix .vendor,$(VNDK_CORE_LIBRARIES)) \
-    $(addsuffix .vendor,$(VNDK_SAMEPROCESS_LIBRARIES)) \
-    $(VNDK_USING_CORE_VARIANT_LIBRARIES)
-
-LOCAL_ADDITIONAL_DEPENDENCIES += $(call module-built-files,\
-    $(addsuffix .vendor,$(VNDK_CORE_LIBRARIES) $(VNDK_SAMEPROCESS_LIBRARIES)))
-
-endif
-include $(BUILD_PHONY_PACKAGE)
-
-include $(CLEAR_VARS)
 
 LOCAL_MODULE := vndk_apex_snapshot_package
 LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
diff --git a/target/product/handheld_system_ext.mk b/target/product/handheld_system_ext.mk
index 1218f7a..187b627 100644
--- a/target/product/handheld_system_ext.mk
+++ b/target/product/handheld_system_ext.mk
@@ -29,8 +29,3 @@
     StorageManager \
     SystemUI \
     WallpaperCropper \
-
-# Base modules when shipping api level is less than or equal to 34
-PRODUCT_PACKAGES_SHIPPING_API_LEVEL_34 += \
-    hwservicemanager \
-    android.hidl.allocator@1.0-service \
diff --git a/target/product/virtual_ab_ota/android_t_baseline.mk b/target/product/virtual_ab_ota/android_t_baseline.mk
index af0f7a9..418aaa4 100644
--- a/target/product/virtual_ab_ota/android_t_baseline.mk
+++ b/target/product/virtual_ab_ota/android_t_baseline.mk
@@ -20,5 +20,3 @@
 #
 # All U+ launching devices should instead use vabc_features.mk.
 $(call inherit-product, $(SRC_TARGET_DIR)/product/virtual_ab_ota/vabc_features.mk)
-
-PRODUCT_VIRTUAL_AB_COW_VERSION ?= 2
diff --git a/tools/aconfig/aconfig/src/codegen/java.rs b/tools/aconfig/aconfig/src/codegen/java.rs
index 920d5fa..18a4be5 100644
--- a/tools/aconfig/aconfig/src/codegen/java.rs
+++ b/tools/aconfig/aconfig/src/codegen/java.rs
@@ -180,8 +180,8 @@
     import android.compat.annotation.UnsupportedAppUsage;
     /** @hide */
     public interface FeatureFlags {
-        @com.android.aconfig.annotations.AconfigFlagAccessor
         @com.android.aconfig.annotations.AssumeFalseForR8
+        @com.android.aconfig.annotations.AconfigFlagAccessor
         @UnsupportedAppUsage
         boolean disabledRo();
         @com.android.aconfig.annotations.AconfigFlagAccessor
@@ -193,20 +193,20 @@
         @com.android.aconfig.annotations.AconfigFlagAccessor
         @UnsupportedAppUsage
         boolean disabledRwInOtherNamespace();
-        @com.android.aconfig.annotations.AconfigFlagAccessor
         @com.android.aconfig.annotations.AssumeTrueForR8
+        @com.android.aconfig.annotations.AconfigFlagAccessor
         @UnsupportedAppUsage
         boolean enabledFixedRo();
-        @com.android.aconfig.annotations.AconfigFlagAccessor
         @com.android.aconfig.annotations.AssumeTrueForR8
+        @com.android.aconfig.annotations.AconfigFlagAccessor
         @UnsupportedAppUsage
         boolean enabledFixedRoExported();
-        @com.android.aconfig.annotations.AconfigFlagAccessor
         @com.android.aconfig.annotations.AssumeTrueForR8
+        @com.android.aconfig.annotations.AconfigFlagAccessor
         @UnsupportedAppUsage
         boolean enabledRo();
-        @com.android.aconfig.annotations.AconfigFlagAccessor
         @com.android.aconfig.annotations.AssumeTrueForR8
+        @com.android.aconfig.annotations.AconfigFlagAccessor
         @UnsupportedAppUsage
         boolean enabledRoExported();
         @com.android.aconfig.annotations.AconfigFlagAccessor
@@ -240,8 +240,8 @@
         /** @hide */
         public static final String FLAG_ENABLED_RW = "com.android.aconfig.test.enabled_rw";
 
-        @com.android.aconfig.annotations.AconfigFlagAccessor
         @com.android.aconfig.annotations.AssumeFalseForR8
+        @com.android.aconfig.annotations.AconfigFlagAccessor
         @UnsupportedAppUsage
         public static boolean disabledRo() {
             return FEATURE_FLAGS.disabledRo();
@@ -261,26 +261,26 @@
         public static boolean disabledRwInOtherNamespace() {
             return FEATURE_FLAGS.disabledRwInOtherNamespace();
         }
-        @com.android.aconfig.annotations.AconfigFlagAccessor
         @com.android.aconfig.annotations.AssumeTrueForR8
+        @com.android.aconfig.annotations.AconfigFlagAccessor
         @UnsupportedAppUsage
         public static boolean enabledFixedRo() {
             return FEATURE_FLAGS.enabledFixedRo();
         }
-        @com.android.aconfig.annotations.AconfigFlagAccessor
         @com.android.aconfig.annotations.AssumeTrueForR8
+        @com.android.aconfig.annotations.AconfigFlagAccessor
         @UnsupportedAppUsage
         public static boolean enabledFixedRoExported() {
             return FEATURE_FLAGS.enabledFixedRoExported();
         }
-        @com.android.aconfig.annotations.AconfigFlagAccessor
         @com.android.aconfig.annotations.AssumeTrueForR8
+        @com.android.aconfig.annotations.AconfigFlagAccessor
         @UnsupportedAppUsage
         public static boolean enabledRo() {
             return FEATURE_FLAGS.enabledRo();
         }
-        @com.android.aconfig.annotations.AconfigFlagAccessor
         @com.android.aconfig.annotations.AssumeTrueForR8
+        @com.android.aconfig.annotations.AconfigFlagAccessor
         @UnsupportedAppUsage
         public static boolean enabledRoExported() {
             return FEATURE_FLAGS.enabledRoExported();
@@ -476,14 +476,14 @@
                 other_namespace_is_cached = true;
             }
 
-            @com.android.aconfig.annotations.AconfigFlagAccessor
             @Override
+            @com.android.aconfig.annotations.AconfigFlagAccessor
             @UnsupportedAppUsage
             public boolean disabledRo() {
                 return false;
             }
-            @com.android.aconfig.annotations.AconfigFlagAccessor
             @Override
+            @com.android.aconfig.annotations.AconfigFlagAccessor
             @UnsupportedAppUsage
             public boolean disabledRw() {
                 if (!aconfig_test_is_cached) {
@@ -491,8 +491,8 @@
                 }
                 return disabledRw;
             }
-            @com.android.aconfig.annotations.AconfigFlagAccessor
             @Override
+            @com.android.aconfig.annotations.AconfigFlagAccessor
             @UnsupportedAppUsage
             public boolean disabledRwExported() {
                 if (!aconfig_test_is_cached) {
@@ -500,8 +500,8 @@
                 }
                 return disabledRwExported;
             }
-            @com.android.aconfig.annotations.AconfigFlagAccessor
             @Override
+            @com.android.aconfig.annotations.AconfigFlagAccessor
             @UnsupportedAppUsage
             public boolean disabledRwInOtherNamespace() {
                 if (!other_namespace_is_cached) {
@@ -509,32 +509,32 @@
                 }
                 return disabledRwInOtherNamespace;
             }
-            @com.android.aconfig.annotations.AconfigFlagAccessor
             @Override
+            @com.android.aconfig.annotations.AconfigFlagAccessor
             @UnsupportedAppUsage
             public boolean enabledFixedRo() {
                 return true;
             }
-            @com.android.aconfig.annotations.AconfigFlagAccessor
             @Override
+            @com.android.aconfig.annotations.AconfigFlagAccessor
             @UnsupportedAppUsage
             public boolean enabledFixedRoExported() {
                 return true;
             }
-            @com.android.aconfig.annotations.AconfigFlagAccessor
             @Override
+            @com.android.aconfig.annotations.AconfigFlagAccessor
             @UnsupportedAppUsage
             public boolean enabledRo() {
                 return true;
             }
-            @com.android.aconfig.annotations.AconfigFlagAccessor
             @Override
+            @com.android.aconfig.annotations.AconfigFlagAccessor
             @UnsupportedAppUsage
             public boolean enabledRoExported() {
                 return true;
             }
-            @com.android.aconfig.annotations.AconfigFlagAccessor
             @Override
+            @com.android.aconfig.annotations.AconfigFlagAccessor
             @UnsupportedAppUsage
             public boolean enabledRw() {
                 if (!aconfig_test_is_cached) {
@@ -592,15 +592,12 @@
             public static final String FLAG_ENABLED_FIXED_RO_EXPORTED = "com.android.aconfig.test.enabled_fixed_ro_exported";
             /** @hide */
             public static final String FLAG_ENABLED_RO_EXPORTED = "com.android.aconfig.test.enabled_ro_exported";
-            @com.android.aconfig.annotations.AconfigFlagAccessor
             public static boolean disabledRwExported() {
                 return FEATURE_FLAGS.disabledRwExported();
             }
-            @com.android.aconfig.annotations.AconfigFlagAccessor
             public static boolean enabledFixedRoExported() {
                 return FEATURE_FLAGS.enabledFixedRoExported();
             }
-            @com.android.aconfig.annotations.AconfigFlagAccessor
             public static boolean enabledRoExported() {
                 return FEATURE_FLAGS.enabledRoExported();
             }
@@ -612,11 +609,8 @@
         package com.android.aconfig.test;
         /** @hide */
         public interface FeatureFlags {
-            @com.android.aconfig.annotations.AconfigFlagAccessor
             boolean disabledRwExported();
-            @com.android.aconfig.annotations.AconfigFlagAccessor
             boolean enabledFixedRoExported();
-            @com.android.aconfig.annotations.AconfigFlagAccessor
             boolean enabledRoExported();
         }
         "#;
@@ -654,7 +648,6 @@
                 }
                 aconfig_test_is_cached = true;
             }
-            @com.android.aconfig.annotations.AconfigFlagAccessor
             @Override
             public boolean disabledRwExported() {
                 if (!aconfig_test_is_cached) {
@@ -662,7 +655,6 @@
                 }
                 return disabledRwExported;
             }
-            @com.android.aconfig.annotations.AconfigFlagAccessor
             @Override
             public boolean enabledFixedRoExported() {
                 if (!aconfig_test_is_cached) {
@@ -670,7 +662,6 @@
                 }
                 return enabledFixedRoExported;
             }
-            @com.android.aconfig.annotations.AconfigFlagAccessor
             @Override
             public boolean enabledRoExported() {
                 if (!aconfig_test_is_cached) {
@@ -792,64 +783,64 @@
         import android.compat.annotation.UnsupportedAppUsage;
         /** @hide */
         public final class FeatureFlagsImpl implements FeatureFlags {
-            @com.android.aconfig.annotations.AconfigFlagAccessor
             @Override
+            @com.android.aconfig.annotations.AconfigFlagAccessor
             @UnsupportedAppUsage
             public boolean disabledRo() {
                 throw new UnsupportedOperationException(
                     "Method is not implemented.");
             }
-            @com.android.aconfig.annotations.AconfigFlagAccessor
             @Override
+            @com.android.aconfig.annotations.AconfigFlagAccessor
             @UnsupportedAppUsage
             public boolean disabledRw() {
                 throw new UnsupportedOperationException(
                     "Method is not implemented.");
             }
-            @com.android.aconfig.annotations.AconfigFlagAccessor
             @Override
+            @com.android.aconfig.annotations.AconfigFlagAccessor
             @UnsupportedAppUsage
             public boolean disabledRwExported() {
                 throw new UnsupportedOperationException(
                     "Method is not implemented.");
             }
-            @com.android.aconfig.annotations.AconfigFlagAccessor
             @Override
+            @com.android.aconfig.annotations.AconfigFlagAccessor
             @UnsupportedAppUsage
             public boolean disabledRwInOtherNamespace() {
                 throw new UnsupportedOperationException(
                     "Method is not implemented.");
             }
-            @com.android.aconfig.annotations.AconfigFlagAccessor
             @Override
+            @com.android.aconfig.annotations.AconfigFlagAccessor
             @UnsupportedAppUsage
             public boolean enabledFixedRo() {
                 throw new UnsupportedOperationException(
                     "Method is not implemented.");
             }
-            @com.android.aconfig.annotations.AconfigFlagAccessor
             @Override
+            @com.android.aconfig.annotations.AconfigFlagAccessor
             @UnsupportedAppUsage
             public boolean enabledFixedRoExported() {
                 throw new UnsupportedOperationException(
                     "Method is not implemented.");
             }
-            @com.android.aconfig.annotations.AconfigFlagAccessor
             @Override
+            @com.android.aconfig.annotations.AconfigFlagAccessor
             @UnsupportedAppUsage
             public boolean enabledRo() {
                 throw new UnsupportedOperationException(
                     "Method is not implemented.");
             }
-            @com.android.aconfig.annotations.AconfigFlagAccessor
             @Override
+            @com.android.aconfig.annotations.AconfigFlagAccessor
             @UnsupportedAppUsage
             public boolean enabledRoExported() {
                 throw new UnsupportedOperationException(
                     "Method is not implemented.");
             }
-            @com.android.aconfig.annotations.AconfigFlagAccessor
             @Override
+            @com.android.aconfig.annotations.AconfigFlagAccessor
             @UnsupportedAppUsage
             public boolean enabledRw() {
                 throw new UnsupportedOperationException(
@@ -901,28 +892,28 @@
         import android.compat.annotation.UnsupportedAppUsage;
         /** @hide */
         public interface FeatureFlags {
-            @com.android.aconfig.annotations.AconfigFlagAccessor
             @com.android.aconfig.annotations.AssumeFalseForR8
+            @com.android.aconfig.annotations.AconfigFlagAccessor
             @UnsupportedAppUsage
             boolean disabledRo();
-            @com.android.aconfig.annotations.AconfigFlagAccessor
             @com.android.aconfig.annotations.AssumeFalseForR8
+            @com.android.aconfig.annotations.AconfigFlagAccessor
             @UnsupportedAppUsage
             boolean disabledRw();
-            @com.android.aconfig.annotations.AconfigFlagAccessor
             @com.android.aconfig.annotations.AssumeFalseForR8
+            @com.android.aconfig.annotations.AconfigFlagAccessor
             @UnsupportedAppUsage
             boolean disabledRwInOtherNamespace();
-            @com.android.aconfig.annotations.AconfigFlagAccessor
             @com.android.aconfig.annotations.AssumeTrueForR8
+            @com.android.aconfig.annotations.AconfigFlagAccessor
             @UnsupportedAppUsage
             boolean enabledFixedRo();
-            @com.android.aconfig.annotations.AconfigFlagAccessor
             @com.android.aconfig.annotations.AssumeTrueForR8
+            @com.android.aconfig.annotations.AconfigFlagAccessor
             @UnsupportedAppUsage
             boolean enabledRo();
-            @com.android.aconfig.annotations.AconfigFlagAccessor
             @com.android.aconfig.annotations.AssumeTrueForR8
+            @com.android.aconfig.annotations.AconfigFlagAccessor
             @UnsupportedAppUsage
             boolean enabledRw();
         }"#;
@@ -933,38 +924,38 @@
         import android.compat.annotation.UnsupportedAppUsage;
         /** @hide */
         public final class FeatureFlagsImpl implements FeatureFlags {
-            @com.android.aconfig.annotations.AconfigFlagAccessor
             @Override
+            @com.android.aconfig.annotations.AconfigFlagAccessor
             @UnsupportedAppUsage
             public boolean disabledRo() {
                 return false;
             }
-            @com.android.aconfig.annotations.AconfigFlagAccessor
             @Override
+            @com.android.aconfig.annotations.AconfigFlagAccessor
             @UnsupportedAppUsage
             public boolean disabledRw() {
                 return false;
             }
-            @com.android.aconfig.annotations.AconfigFlagAccessor
             @Override
+            @com.android.aconfig.annotations.AconfigFlagAccessor
             @UnsupportedAppUsage
             public boolean disabledRwInOtherNamespace() {
                 return false;
             }
-            @com.android.aconfig.annotations.AconfigFlagAccessor
             @Override
+            @com.android.aconfig.annotations.AconfigFlagAccessor
             @UnsupportedAppUsage
             public boolean enabledFixedRo() {
                 return true;
             }
-            @com.android.aconfig.annotations.AconfigFlagAccessor
             @Override
+            @com.android.aconfig.annotations.AconfigFlagAccessor
             @UnsupportedAppUsage
             public boolean enabledRo() {
                 return true;
             }
-            @com.android.aconfig.annotations.AconfigFlagAccessor
             @Override
+            @com.android.aconfig.annotations.AconfigFlagAccessor
             @UnsupportedAppUsage
             public boolean enabledRw() {
                 return true;
@@ -990,38 +981,38 @@
             public static final String FLAG_ENABLED_RO = "com.android.aconfig.test.enabled_ro";
             /** @hide */
             public static final String FLAG_ENABLED_RW = "com.android.aconfig.test.enabled_rw";
-            @com.android.aconfig.annotations.AconfigFlagAccessor
             @com.android.aconfig.annotations.AssumeFalseForR8
+            @com.android.aconfig.annotations.AconfigFlagAccessor
             @UnsupportedAppUsage
             public static boolean disabledRo() {
                 return FEATURE_FLAGS.disabledRo();
             }
-            @com.android.aconfig.annotations.AconfigFlagAccessor
             @com.android.aconfig.annotations.AssumeFalseForR8
+            @com.android.aconfig.annotations.AconfigFlagAccessor
             @UnsupportedAppUsage
             public static boolean disabledRw() {
                 return FEATURE_FLAGS.disabledRw();
             }
-            @com.android.aconfig.annotations.AconfigFlagAccessor
             @com.android.aconfig.annotations.AssumeFalseForR8
+            @com.android.aconfig.annotations.AconfigFlagAccessor
             @UnsupportedAppUsage
             public static boolean disabledRwInOtherNamespace() {
                 return FEATURE_FLAGS.disabledRwInOtherNamespace();
             }
-            @com.android.aconfig.annotations.AconfigFlagAccessor
             @com.android.aconfig.annotations.AssumeTrueForR8
+            @com.android.aconfig.annotations.AconfigFlagAccessor
             @UnsupportedAppUsage
             public static boolean enabledFixedRo() {
                 return FEATURE_FLAGS.enabledFixedRo();
             }
-            @com.android.aconfig.annotations.AconfigFlagAccessor
             @com.android.aconfig.annotations.AssumeTrueForR8
+            @com.android.aconfig.annotations.AconfigFlagAccessor
             @UnsupportedAppUsage
             public static boolean enabledRo() {
                 return FEATURE_FLAGS.enabledRo();
             }
-            @com.android.aconfig.annotations.AconfigFlagAccessor
             @com.android.aconfig.annotations.AssumeTrueForR8
+            @com.android.aconfig.annotations.AconfigFlagAccessor
             @UnsupportedAppUsage
             public static boolean enabledRw() {
                 return FEATURE_FLAGS.enabledRw();
diff --git a/tools/aconfig/aconfig/src/codegen/rust.rs b/tools/aconfig/aconfig/src/codegen/rust.rs
index 6e6c9e2..db3003d 100644
--- a/tools/aconfig/aconfig/src/codegen/rust.rs
+++ b/tools/aconfig/aconfig/src/codegen/rust.rs
@@ -110,7 +110,7 @@
 // use aconfig_storage_read_api::{StorageFileType, get_mapped_storage_file, get_boolean_flag_value, get_package_offset};
 use std::path::Path;
 use std::io::Write;
-use log::{info, error, LevelFilter};
+use log::{log, LevelFilter, Level};
 
 static STORAGE_MIGRATION_MARKER_FILE: &str =
     "/metadata/aconfig/storage_test_mission_1";
@@ -513,7 +513,7 @@
 // use aconfig_storage_read_api::{StorageFileType, get_mapped_storage_file, get_boolean_flag_value, get_package_offset};
 use std::path::Path;
 use std::io::Write;
-use log::{info, error, LevelFilter};
+use log::{log, LevelFilter, Level};
 
 static STORAGE_MIGRATION_MARKER_FILE: &str =
     "/metadata/aconfig/storage_test_mission_1";
@@ -587,7 +587,7 @@
 // use aconfig_storage_read_api::{StorageFileType, get_mapped_storage_file, get_boolean_flag_value, get_package_offset};
 use std::path::Path;
 use std::io::Write;
-use log::{info, error, LevelFilter};
+use log::{log, LevelFilter, Level};
 
 static STORAGE_MIGRATION_MARKER_FILE: &str =
     "/metadata/aconfig/storage_test_mission_1";
diff --git a/tools/aconfig/aconfig/templates/FeatureFlags.java.template b/tools/aconfig/aconfig/templates/FeatureFlags.java.template
index b90b201..38c8f13 100644
--- a/tools/aconfig/aconfig/templates/FeatureFlags.java.template
+++ b/tools/aconfig/aconfig/templates/FeatureFlags.java.template
@@ -6,7 +6,6 @@
 /** @hide */
 public interface FeatureFlags \{
 {{ for item in flag_elements }}
-    @com.android.aconfig.annotations.AconfigFlagAccessor
 {{ -if not item.is_read_write }}
 {{ -if item.default_value }}
     @com.android.aconfig.annotations.AssumeTrueForR8
@@ -15,6 +14,7 @@
 {{ -endif- }}
 {{ -endif }}
 {{ -if not library_exported }}
+    @com.android.aconfig.annotations.AconfigFlagAccessor
     @UnsupportedAppUsage
 {{ -endif }}
     boolean {item.method_name}();
diff --git a/tools/aconfig/aconfig/templates/FeatureFlagsImpl.java.template b/tools/aconfig/aconfig/templates/FeatureFlagsImpl.java.template
index 704f25b..6235e69 100644
--- a/tools/aconfig/aconfig/templates/FeatureFlagsImpl.java.template
+++ b/tools/aconfig/aconfig/templates/FeatureFlagsImpl.java.template
@@ -45,9 +45,9 @@
 {{ endfor- }}
 {{ -endif }}{#- end of runtime_lookup_required #}
 {{ -for flag in flag_elements }}
-    @com.android.aconfig.annotations.AconfigFlagAccessor
     @Override
 {{ -if not library_exported }}
+    @com.android.aconfig.annotations.AconfigFlagAccessor
     @UnsupportedAppUsage
 {{ -endif }}
     public boolean {flag.method_name}() \{
@@ -67,9 +67,9 @@
 /** @hide */
 public final class FeatureFlagsImpl implements FeatureFlags \{
 {{ for flag in flag_elements }}
-    @com.android.aconfig.annotations.AconfigFlagAccessor
     @Override
 {{ -if not library_exported }}
+    @com.android.aconfig.annotations.AconfigFlagAccessor
     @UnsupportedAppUsage
 {{ -endif }}
     public boolean {flag.method_name}() \{
diff --git a/tools/aconfig/aconfig/templates/Flags.java.template b/tools/aconfig/aconfig/templates/Flags.java.template
index 55db924..e2f70b9 100644
--- a/tools/aconfig/aconfig/templates/Flags.java.template
+++ b/tools/aconfig/aconfig/templates/Flags.java.template
@@ -10,7 +10,6 @@
     public static final String FLAG_{item.flag_name_constant_suffix} = "{item.device_config_flag}";
 {{- endfor }}
 {{ -for item in flag_elements}}
-    @com.android.aconfig.annotations.AconfigFlagAccessor
 {{ -if not item.is_read_write }}
 {{ -if item.default_value }}
     @com.android.aconfig.annotations.AssumeTrueForR8
@@ -19,6 +18,7 @@
 {{ -endif }}
 {{ -endif }}
 {{ -if not library_exported }}
+    @com.android.aconfig.annotations.AconfigFlagAccessor
     @UnsupportedAppUsage
 {{ -endif }}
     public static boolean {item.method_name}() \{
diff --git a/tools/aconfig/aconfig/templates/rust.template b/tools/aconfig/aconfig/templates/rust.template
index 3cc989e..2f97c14 100644
--- a/tools/aconfig/aconfig/templates/rust.template
+++ b/tools/aconfig/aconfig/templates/rust.template
@@ -3,7 +3,7 @@
 // use aconfig_storage_read_api::\{StorageFileType, get_mapped_storage_file, get_boolean_flag_value, get_package_offset};
 use std::path::Path;
 use std::io::Write;
-use log::\{info, error, LevelFilter};
+use log::\{log, LevelFilter, Level};
 
 static STORAGE_MIGRATION_MARKER_FILE: &str =
     "/metadata/aconfig/storage_test_mission_1";
@@ -74,41 +74,41 @@
         let package_map = match get_mapped_storage_file("{flag.container}", StorageFileType::PackageMap) \{
             Ok(file) => file,
             Err(err) => \{
-                error!("failed to read flag '{flag.name}': \{}", err);
+                log!(Level::Error, "AconfigTestMission1: error: failed to read flag '{flag.name}': \{err}");
                 return result;
             }
         };
         let package_offset = match get_package_offset(&package_map, "{package}") \{
             Ok(Some(offset)) => offset,
             Ok(None) => \{
-                error!("failed to read flag '{flag.name}', not found in package map");
+                log!(Level::Error, "AconfigTestMission1: error: failed to read flag '{flag.name}': did not find offset");
                 return result;
             },
             Err(err) => \{
-                error!("failed to read flag '{flag.name}': \{}", err);
+                log!(Level::Error, "AconfigTestMission1: error: failed to read flag '{flag.name}': \{err}");
                 return result;
             }
         };
         let flag_val_map = match get_mapped_storage_file("{flag.container}", StorageFileType::FlagVal) \{
             Ok(val_map) => val_map,
             Err(err) => \{
-                error!("failed to read flag '{flag.name}': \{}", err);
+                log!(Level::Error, "AconfigTestMission1: error: failed to read flag '{flag.name}': \{err}");
                 return result;
             }
         };
         let value = match get_boolean_flag_value(&flag_val_map, {flag.flag_offset} + package_offset.boolean_offset) \{
             Ok(val) => val,
             Err(err) => \{
-                error!("failed to read flag '{flag.name}': \{}", err);
+                log!(Level::Error, "AconfigTestMission1: error: failed to read flag '{flag.name}': \{err}");
                 return result;
             }
         };
 
         if result != value \{
-            error!("error: flag mismatch for '{flag.name}'. Legacy storage was \{result}, new storage was \{value}")
+            log!(Level::Error, "AconfigTestMission1: error: flag mismatch for '{flag.name}'. Legacy storage was \{result}, new storage was \{value}");
         } else \{
             let default_value = {flag.default_value};
-            info!("success! flag '{flag.name}' contained correct value. Legacy storage was \{default_value}, new storage was \{value}")
+            log!(Level::Info, "AconfigTestMission1: success! flag '{flag.name}' contained correct value. Legacy storage was \{default_value}, new storage was \{value}");
         }
     }
 
diff --git a/tools/aconfig/aconfig_storage_file/protos/aconfig_storage_metadata.proto b/tools/aconfig/aconfig_storage_file/protos/aconfig_storage_metadata.proto
index c6728bd..e1c1c7f 100644
--- a/tools/aconfig/aconfig_storage_file/protos/aconfig_storage_metadata.proto
+++ b/tools/aconfig/aconfig_storage_file/protos/aconfig_storage_metadata.proto
@@ -26,7 +26,8 @@
   optional string package_map = 3;
   optional string flag_map = 4;
   optional string flag_val = 5;
-  optional int64 timestamp = 6;
+  optional string flag_info = 6;
+  optional int64 timestamp = 7;
 }
 
 message storage_files {
diff --git a/tools/aconfig/aconfig_storage_file/src/flag_info.rs b/tools/aconfig/aconfig_storage_file/src/flag_info.rs
index 3fff263..dc2a8d6 100644
--- a/tools/aconfig/aconfig_storage_file/src/flag_info.rs
+++ b/tools/aconfig/aconfig_storage_file/src/flag_info.rs
@@ -91,9 +91,9 @@
 /// bit field for flag info
 #[derive(Clone, Debug, PartialEq, Eq)]
 pub enum FlagInfoBit {
-    IsSticky = 0,
-    IsReadWrite = 1,
-    HasOverride = 2,
+    IsSticky = 1 << 0,
+    IsReadWrite = 1 << 1,
+    HasOverride = 1 << 2,
 }
 
 /// Flag info node struct
@@ -108,9 +108,9 @@
         writeln!(
             f,
             "sticky: {}, readwrite: {}, override: {}",
-            self.attributes & (FlagInfoBit::IsSticky as u8),
-            self.attributes & (FlagInfoBit::IsReadWrite as u8),
-            self.attributes & (FlagInfoBit::HasOverride as u8),
+            self.attributes & (FlagInfoBit::IsSticky as u8) != 0,
+            self.attributes & (FlagInfoBit::IsReadWrite as u8) != 0,
+            self.attributes & (FlagInfoBit::HasOverride as u8) != 0,
         )?;
         Ok(())
     }
diff --git a/tools/aconfig/aconfig_storage_file/src/lib.rs b/tools/aconfig/aconfig_storage_file/src/lib.rs
index 3b975d9..a7b977a 100644
--- a/tools/aconfig/aconfig_storage_file/src/lib.rs
+++ b/tools/aconfig/aconfig_storage_file/src/lib.rs
@@ -44,16 +44,14 @@
 use std::collections::hash_map::DefaultHasher;
 use std::fs::File;
 use std::hash::{Hash, Hasher};
-use std::io::{Read, Write};
+use std::io::Read;
 
-pub use crate::flag_info::{FlagInfoHeader, FlagInfoList, FlagInfoNode};
+pub use crate::flag_info::{FlagInfoHeader, FlagInfoList, FlagInfoNode, FlagInfoBit};
 pub use crate::flag_table::{FlagTable, FlagTableHeader, FlagTableNode};
 pub use crate::flag_value::{FlagValueHeader, FlagValueList};
 pub use crate::package_table::{PackageTable, PackageTableHeader, PackageTableNode};
 
-use crate::AconfigStorageError::{
-    BytesParseFail, FileCreationFail, HashTableSizeLimit, InvalidStoredFlagType,
-};
+use crate::AconfigStorageError::{BytesParseFail, HashTableSizeLimit, InvalidStoredFlagType};
 
 /// Storage file version
 pub const FILE_VERSION: u32 = 1;
@@ -105,6 +103,7 @@
 }
 
 /// Flag type enum as stored by storage file
+/// ONLY APPEND, NEVER REMOVE FOR BACKWARD COMPATOBILITY. THE MAX IS U16.
 #[derive(Clone, Copy, Debug, PartialEq, Eq)]
 pub enum StoredFlagType {
     ReadWriteBoolean = 0,
@@ -279,67 +278,13 @@
     Ok(flags)
 }
 
-/// Create flag info file
-pub fn create_flag_info(
-    package_map: &str,
-    flag_map: &str,
-    flag_info_out: &str,
-) -> Result<(), AconfigStorageError> {
-    let package_table = PackageTable::from_bytes(&read_file_to_bytes(package_map)?)?;
-    let flag_table = FlagTable::from_bytes(&read_file_to_bytes(flag_map)?)?;
-
-    if package_table.header.container != flag_table.header.container {
-        return Err(FileCreationFail(anyhow!(
-            "container for package map {} and flag map {} does not match",
-            package_table.header.container,
-            flag_table.header.container,
-        )));
-    }
-
-    let mut package_offsets = vec![0; package_table.header.num_packages as usize];
-    for node in package_table.nodes.iter() {
-        package_offsets[node.package_id as usize] = node.boolean_offset;
-    }
-
-    let mut is_flag_rw = vec![false; flag_table.header.num_flags as usize];
-    for node in flag_table.nodes.iter() {
-        let flag_offset = package_offsets[node.package_id as usize] + node.flag_id as u32;
-        is_flag_rw[flag_offset as usize] = node.flag_type == StoredFlagType::ReadWriteBoolean;
-    }
-
-    let mut list = FlagInfoList {
-        header: FlagInfoHeader {
-            version: FILE_VERSION,
-            container: flag_table.header.container,
-            file_type: StorageFileType::FlagInfo as u8,
-            file_size: 0,
-            num_flags: flag_table.header.num_flags,
-            boolean_flag_offset: 0,
-        },
-        nodes: is_flag_rw.iter().map(|&rw| FlagInfoNode::create(rw)).collect(),
-    };
-
-    list.header.boolean_flag_offset = list.header.into_bytes().len() as u32;
-    list.header.file_size = list.into_bytes().len() as u32;
-
-    let mut file = File::create(flag_info_out).map_err(|errmsg| {
-        FileCreationFail(anyhow!("fail to create file {}: {}", flag_info_out, errmsg))
-    })?;
-    file.write_all(&list.into_bytes()).map_err(|errmsg| {
-        FileCreationFail(anyhow!("fail to write to file {}: {}", flag_info_out, errmsg))
-    })?;
-
-    Ok(())
-}
-
 #[cfg(test)]
 mod tests {
     use super::*;
     use crate::test_utils::{
-        create_test_flag_info_list, create_test_flag_table, create_test_flag_value_list,
-        create_test_package_table, write_bytes_to_temp_file,
+        create_test_flag_table, create_test_flag_value_list, create_test_package_table,
+        write_bytes_to_temp_file,
     };
-    use tempfile::NamedTempFile;
 
     #[test]
     // this test point locks down the flag list api
@@ -408,31 +353,4 @@
         ];
         assert_eq!(flags, expected);
     }
-
-    fn create_empty_temp_file() -> Result<NamedTempFile, AconfigStorageError> {
-        let file = NamedTempFile::new().map_err(|_| {
-            AconfigStorageError::FileCreationFail(anyhow!("Failed to create temp file"))
-        })?;
-        Ok(file)
-    }
-
-    #[test]
-    // this test point locks down the flag info creation
-    fn test_create_flag_info() {
-        let package_table =
-            write_bytes_to_temp_file(&create_test_package_table().into_bytes()).unwrap();
-        let flag_table = write_bytes_to_temp_file(&create_test_flag_table().into_bytes()).unwrap();
-        let flag_info = create_empty_temp_file().unwrap();
-
-        let package_table_path = package_table.path().display().to_string();
-        let flag_table_path = flag_table.path().display().to_string();
-        let flag_info_path = flag_info.path().display().to_string();
-
-        assert!(create_flag_info(&package_table_path, &flag_table_path, &flag_info_path).is_ok());
-
-        let flag_info =
-            FlagInfoList::from_bytes(&read_file_to_bytes(&flag_info_path).unwrap()).unwrap();
-        let expected_flag_info = create_test_flag_info_list();
-        assert_eq!(flag_info, expected_flag_info);
-    }
 }
diff --git a/tools/aconfig/aconfig_storage_read_api/Android.bp b/tools/aconfig/aconfig_storage_read_api/Android.bp
index b252e9d..3746d17 100644
--- a/tools/aconfig/aconfig_storage_read_api/Android.bp
+++ b/tools/aconfig/aconfig_storage_read_api/Android.bp
@@ -38,6 +38,7 @@
         "tests/package.map",
         "tests/flag.map",
         "tests/flag.val",
+        "tests/flag.info",
     ],
 }
 
diff --git a/tools/aconfig/aconfig_storage_read_api/aconfig_storage_read_api.cpp b/tools/aconfig/aconfig_storage_read_api/aconfig_storage_read_api.cpp
index 2213831..ad5656a 100644
--- a/tools/aconfig/aconfig_storage_read_api/aconfig_storage_read_api.cpp
+++ b/tools/aconfig/aconfig_storage_read_api/aconfig_storage_read_api.cpp
@@ -54,6 +54,8 @@
           return entry.flag_map();
         case StorageFileType::flag_val:
           return entry.flag_val();
+        case StorageFileType::flag_info:
+          return entry.flag_info();
         default:
           return Error() << "Invalid file type " << file_type;
       }
@@ -153,7 +155,8 @@
   if (offset_cxx.query_success) {
     auto offset = FlagOffset();
     offset.flag_exists = offset_cxx.flag_exists;
-    offset.flag_offset = offset_cxx.flag_offset;
+    offset.flag_type = static_cast<StoredFlagType>(offset_cxx.flag_type);
+    offset.flag_id = offset_cxx.flag_id;
     return offset;
   } else {
    return Error() << offset_cxx.error_message;
@@ -174,4 +177,17 @@
   }
 }
 
+/// Get boolean flag attribute
+Result<uint8_t> get_boolean_flag_attribute(
+    MappedStorageFile const& file,
+    uint32_t offset) {
+  auto content = rust::Slice<const uint8_t>(
+      static_cast<uint8_t*>(file.file_ptr), file.file_size);
+  auto info_cxx = get_boolean_flag_attribute_cxx(content, offset);
+  if (info_cxx.query_success) {
+    return info_cxx.flag_attribute;
+  } else {
+    return Error() << info_cxx.error_message;
+  }
+}
 } // namespace aconfig_storage
diff --git a/tools/aconfig/aconfig_storage_read_api/include/aconfig_storage/aconfig_storage_read_api.hpp b/tools/aconfig/aconfig_storage_read_api/include/aconfig_storage/aconfig_storage_read_api.hpp
index aa90f47..b2a6e41 100644
--- a/tools/aconfig/aconfig_storage_read_api/include/aconfig_storage/aconfig_storage_read_api.hpp
+++ b/tools/aconfig/aconfig_storage_read_api/include/aconfig_storage/aconfig_storage_read_api.hpp
@@ -10,7 +10,8 @@
 enum StorageFileType {
   package_map,
   flag_map,
-  flag_val
+  flag_val,
+  flag_info
 };
 
 /// Mapped storage file
@@ -26,10 +27,18 @@
   uint32_t boolean_offset;
 };
 
+/// Flag type enum, to be consistent with the one defined in aconfig_storage_file/src/lib.rs
+enum StoredFlagType {
+  ReadWriteBoolean = 0,
+  ReadOnlyBoolean = 1,
+  FixedReadOnlyBoolean = 2,
+};
+
 /// Flag offset query result
 struct FlagOffset {
   bool flag_exists;
-  uint16_t flag_offset;
+  StoredFlagType flag_type;
+  uint16_t flag_id;
 };
 
 /// DO NOT USE APIS IN THE FOLLOWING NAMESPACE DIRECTLY
@@ -76,10 +85,24 @@
 
 /// Get boolean flag value
 /// \input file: mapped storage file
-/// \input offset: the boolean flag value byte offset in the file
+/// \input offset: the boolean flag value offset in the file
 /// \returns the boolean flag value
 android::base::Result<bool> get_boolean_flag_value(
     MappedStorageFile const& file,
     uint32_t offset);
 
+/// Flag info enum, to be consistent with the one defined in aconfig_storage_file/src/lib.rs
+enum FlagInfoBit {
+  IsSticky = 1<<0,
+  IsReadWrite = 1<<1,
+  HasOverride = 1<<2,
+};
+
+/// Get boolean flag attribute
+/// \input file: mapped storage file
+/// \input offset: the boolean flag info offset in the file
+/// \returns the boolean flag attribute
+android::base::Result<uint8_t> get_boolean_flag_attribute(
+    MappedStorageFile const& file,
+    uint32_t offset);
 } // namespace aconfig_storage
diff --git a/tools/aconfig/aconfig_storage_read_api/src/flag_info_query.rs b/tools/aconfig/aconfig_storage_read_api/src/flag_info_query.rs
new file mode 100644
index 0000000..2f8c536
--- /dev/null
+++ b/tools/aconfig/aconfig_storage_read_api/src/flag_info_query.rs
@@ -0,0 +1,115 @@
+/*
+ * 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.
+ */
+
+//! flag value query module defines the flag value file read from mapped bytes
+
+use crate::{AconfigStorageError, FILE_VERSION};
+use aconfig_storage_file::{flag_info::FlagInfoHeader, read_u8_from_bytes};
+use anyhow::anyhow;
+
+/// Get flag attribute bitfield
+pub fn find_boolean_flag_attribute(
+    buf: &[u8],
+    flag_offset: u32,
+) -> Result<u8, AconfigStorageError> {
+    let interpreted_header = FlagInfoHeader::from_bytes(buf)?;
+    if interpreted_header.version > crate::FILE_VERSION {
+        return Err(AconfigStorageError::HigherStorageFileVersion(anyhow!(
+            "Cannot read storage file with a higher version of {} with lib version {}",
+            interpreted_header.version,
+            FILE_VERSION
+        )));
+    }
+
+    let mut head = (interpreted_header.boolean_flag_offset + flag_offset) as usize;
+
+    if head >= interpreted_header.file_size as usize {
+        return Err(AconfigStorageError::InvalidStorageFileOffset(anyhow!(
+            "Flag info offset goes beyond the end of the file."
+        )));
+    }
+
+    let val = read_u8_from_bytes(buf, &mut head)?;
+    Ok(val)
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+    use aconfig_storage_file::{test_utils::create_test_flag_info_list, FlagInfoBit};
+
+    #[test]
+    // this test point locks down query if flag is sticky
+    fn test_is_flag_sticky() {
+        let flag_info_list = create_test_flag_info_list().into_bytes();
+        for offset in 0..8 {
+            let attribute = find_boolean_flag_attribute(&flag_info_list[..], offset).unwrap();
+            assert_eq!((attribute & FlagInfoBit::IsSticky as u8) != 0u8, false);
+        }
+    }
+
+    #[test]
+    // this test point locks down query if flag is readwrite
+    fn test_is_flag_readwrite() {
+        let flag_info_list = create_test_flag_info_list().into_bytes();
+        let baseline: Vec<bool> = vec![true, false, true, false, false, false, false, false];
+        for offset in 0..8 {
+            let attribute = find_boolean_flag_attribute(&flag_info_list[..], offset).unwrap();
+            assert_eq!(
+                (attribute & FlagInfoBit::IsReadWrite as u8) != 0u8,
+                baseline[offset as usize]
+            );
+        }
+    }
+
+    #[test]
+    // this test point locks down query if flag has override
+    fn test_flag_has_override() {
+        let flag_info_list = create_test_flag_info_list().into_bytes();
+        for offset in 0..8 {
+            let attribute = find_boolean_flag_attribute(&flag_info_list[..], offset).unwrap();
+            assert_eq!((attribute & FlagInfoBit::HasOverride as u8) != 0u8, false);
+        }
+    }
+
+    #[test]
+    // this test point locks down query beyond the end of boolean section
+    fn test_boolean_out_of_range() {
+        let flag_info_list = create_test_flag_info_list().into_bytes();
+        let error = find_boolean_flag_attribute(&flag_info_list[..], 8).unwrap_err();
+        assert_eq!(
+            format!("{:?}", error),
+            "InvalidStorageFileOffset(Flag info offset goes beyond the end of the file.)"
+        );
+    }
+
+    #[test]
+    // this test point locks down query error when file has a higher version
+    fn test_higher_version_storage_file() {
+        let mut info_list = create_test_flag_info_list();
+        info_list.header.version = crate::FILE_VERSION + 1;
+        let flag_info = info_list.into_bytes();
+        let error = find_boolean_flag_attribute(&flag_info[..], 4).unwrap_err();
+        assert_eq!(
+            format!("{:?}", error),
+            format!(
+                "HigherStorageFileVersion(Cannot read storage file with a higher version of {} with lib version {})",
+                crate::FILE_VERSION + 1,
+                crate::FILE_VERSION
+            )
+        );
+    }
+}
diff --git a/tools/aconfig/aconfig_storage_read_api/src/flag_table_query.rs b/tools/aconfig/aconfig_storage_read_api/src/flag_table_query.rs
index a251b41..ad8e394 100644
--- a/tools/aconfig/aconfig_storage_read_api/src/flag_table_query.rs
+++ b/tools/aconfig/aconfig_storage_read_api/src/flag_table_query.rs
@@ -18,11 +18,16 @@
 
 use crate::{AconfigStorageError, FILE_VERSION};
 use aconfig_storage_file::{
-    flag_table::FlagTableHeader, flag_table::FlagTableNode, read_u32_from_bytes,
+    flag_table::FlagTableHeader, flag_table::FlagTableNode, read_u32_from_bytes, StoredFlagType,
 };
 use anyhow::anyhow;
 
-pub type FlagOffset = u16;
+/// Flag table query return
+#[derive(PartialEq, Debug)]
+pub struct FlagOffset {
+    pub flag_type: StoredFlagType,
+    pub flag_id: u16,
+}
 
 /// Query flag within package offset
 pub fn find_flag_offset(
@@ -53,7 +58,10 @@
     loop {
         let interpreted_node = FlagTableNode::from_bytes(&buf[flag_node_offset..])?;
         if interpreted_node.package_id == package_id && interpreted_node.flag_name == flag {
-            return Ok(Some(interpreted_node.flag_id));
+            return Ok(Some(FlagOffset {
+                flag_type: interpreted_node.flag_type,
+                flag_id: interpreted_node.flag_id,
+            }));
         }
         match interpreted_node.next_offset {
             Some(offset) => flag_node_offset = offset as usize,
@@ -72,19 +80,20 @@
     fn test_flag_query() {
         let flag_table = create_test_flag_table().into_bytes();
         let baseline = vec![
-            (0, "enabled_ro", 1u16),
-            (0, "enabled_rw", 2u16),
-            (1, "disabled_ro", 0u16),
-            (2, "enabled_ro", 1u16),
-            (1, "enabled_fixed_ro", 1u16),
-            (1, "enabled_ro", 2u16),
-            (2, "enabled_fixed_ro", 0u16),
-            (0, "disabled_rw", 0u16),
+            (0, "enabled_ro", StoredFlagType::ReadOnlyBoolean, 1u16),
+            (0, "enabled_rw", StoredFlagType::ReadWriteBoolean, 2u16),
+            (1, "disabled_ro", StoredFlagType::ReadOnlyBoolean, 0u16),
+            (2, "enabled_ro", StoredFlagType::ReadOnlyBoolean, 1u16),
+            (1, "enabled_fixed_ro", StoredFlagType::FixedReadOnlyBoolean, 1u16),
+            (1, "enabled_ro", StoredFlagType::ReadOnlyBoolean, 2u16),
+            (2, "enabled_fixed_ro", StoredFlagType::FixedReadOnlyBoolean, 0u16),
+            (0, "disabled_rw", StoredFlagType::ReadWriteBoolean, 0u16),
         ];
-        for (package_id, flag_name, expected_offset) in baseline.into_iter() {
+        for (package_id, flag_name, flag_type, flag_id) in baseline.into_iter() {
             let flag_offset =
                 find_flag_offset(&flag_table[..], package_id, flag_name).unwrap().unwrap();
-            assert_eq!(flag_offset, expected_offset);
+            assert_eq!(flag_offset.flag_type, flag_type);
+            assert_eq!(flag_offset.flag_id, flag_id);
         }
     }
 
diff --git a/tools/aconfig/aconfig_storage_read_api/src/flag_value_query.rs b/tools/aconfig/aconfig_storage_read_api/src/flag_value_query.rs
index 964cd69..7324f43 100644
--- a/tools/aconfig/aconfig_storage_read_api/src/flag_value_query.rs
+++ b/tools/aconfig/aconfig_storage_read_api/src/flag_value_query.rs
@@ -48,26 +48,13 @@
 #[cfg(test)]
 mod tests {
     use super::*;
-    use aconfig_storage_file::{FlagValueList, StorageFileType};
-
-    pub fn create_test_flag_value_list() -> FlagValueList {
-        let header = FlagValueHeader {
-            version: crate::FILE_VERSION,
-            container: String::from("system"),
-            file_type: StorageFileType::FlagVal as u8,
-            file_size: 35,
-            num_flags: 8,
-            boolean_value_offset: 27,
-        };
-        let booleans: Vec<bool> = vec![false, true, false, false, true, true, false, true];
-        FlagValueList { header, booleans }
-    }
+    use aconfig_storage_file::test_utils::create_test_flag_value_list;
 
     #[test]
     // this test point locks down flag value query
     fn test_flag_value_query() {
         let flag_value_list = create_test_flag_value_list().into_bytes();
-        let baseline: Vec<bool> = vec![false, true, false, false, true, true, false, true];
+        let baseline: Vec<bool> = vec![false, true, true, false, true, true, true, true];
         for (offset, expected_value) in baseline.into_iter().enumerate() {
             let flag_value = find_boolean_flag_value(&flag_value_list[..], offset as u32).unwrap();
             assert_eq!(flag_value, expected_value);
diff --git a/tools/aconfig/aconfig_storage_read_api/src/lib.rs b/tools/aconfig/aconfig_storage_read_api/src/lib.rs
index da64cb7..960446d 100644
--- a/tools/aconfig/aconfig_storage_read_api/src/lib.rs
+++ b/tools/aconfig/aconfig_storage_read_api/src/lib.rs
@@ -34,6 +34,7 @@
 //! apis. DO NOT DIRECTLY USE THESE APIS IN YOUR SOURCE CODE. For auto generated flag apis
 //! please refer to the g3doc go/android-flags
 
+pub mod flag_info_query;
 pub mod flag_table_query;
 pub mod flag_value_query;
 pub mod mapped_file;
@@ -47,6 +48,7 @@
 pub use package_table_query::PackageOffset;
 
 use aconfig_storage_file::{read_u32_from_bytes, FILE_VERSION};
+use flag_info_query::find_boolean_flag_attribute;
 use flag_table_query::find_flag_offset;
 use flag_value_query::find_boolean_flag_value;
 use package_table_query::find_package_offset;
@@ -145,6 +147,18 @@
     read_u32_from_bytes(&buffer, &mut head)
 }
 
+/// Get the boolean flag attribute.
+///
+/// \input file: mapped flag info file
+/// \input offset: boolean flag offset
+///
+/// \return
+/// If the provide offset is valid, it returns the boolean flag attribute bitfiled, otherwise it
+/// returns the error message.
+pub fn get_boolean_flag_attribute(file: &Mmap, offset: u32) -> Result<u8, AconfigStorageError> {
+    find_boolean_flag_attribute(file, offset)
+}
+
 // *************************************** //
 // CC INTERLOP
 // *************************************** //
@@ -173,7 +187,8 @@
         pub query_success: bool,
         pub error_message: String,
         pub flag_exists: bool,
-        pub flag_offset: u16,
+        pub flag_type: u16,
+        pub flag_id: u16,
     }
 
     // Flag value query return for cc interlop
@@ -183,6 +198,13 @@
         pub flag_value: bool,
     }
 
+    // Flag info query return for cc interlop
+    pub struct BooleanFlagAttributeQueryCXX {
+        pub query_success: bool,
+        pub error_message: String,
+        pub flag_attribute: u8,
+    }
+
     // Rust export to c++
     extern "Rust" {
         pub fn get_storage_file_version_cxx(file_path: &str) -> VersionNumberQueryCXX;
@@ -192,6 +214,11 @@
         pub fn get_flag_offset_cxx(file: &[u8], package_id: u32, flag: &str) -> FlagOffsetQueryCXX;
 
         pub fn get_boolean_flag_value_cxx(file: &[u8], offset: u32) -> BooleanFlagValueQueryCXX;
+
+        pub fn get_boolean_flag_attribute_cxx(
+            file: &[u8],
+            offset: u32,
+        ) -> BooleanFlagAttributeQueryCXX;
     }
 }
 
@@ -235,20 +262,23 @@
                     query_success: true,
                     error_message: String::from(""),
                     flag_exists: true,
-                    flag_offset: offset,
+                    flag_type: offset.flag_type as u16,
+                    flag_id: offset.flag_id,
                 },
                 None => Self {
                     query_success: true,
                     error_message: String::from(""),
                     flag_exists: false,
-                    flag_offset: 0,
+                    flag_type: 0u16,
+                    flag_id: 0u16,
                 },
             },
             Err(errmsg) => Self {
                 query_success: false,
                 error_message: format!("{:?}", errmsg),
                 flag_exists: false,
-                flag_offset: 0,
+                flag_type: 0u16,
+                flag_id: 0u16,
             },
         }
     }
@@ -270,6 +300,22 @@
     }
 }
 
+/// Implement the flag info interlop return type, create from actual flag info api return type
+impl ffi::BooleanFlagAttributeQueryCXX {
+    pub(crate) fn new(info_result: Result<u8, AconfigStorageError>) -> Self {
+        match info_result {
+            Ok(info) => {
+                Self { query_success: true, error_message: String::from(""), flag_attribute: info }
+            }
+            Err(errmsg) => Self {
+                query_success: false,
+                error_message: format!("{:?}", errmsg),
+                flag_attribute: 0u8,
+            },
+        }
+    }
+}
+
 /// Implement the storage version number interlop return type, create from actual version number
 /// api return type
 impl ffi::VersionNumberQueryCXX {
@@ -304,6 +350,14 @@
     ffi::BooleanFlagValueQueryCXX::new(find_boolean_flag_value(file, offset))
 }
 
+/// Get boolean flag attribute cc interlop
+pub fn get_boolean_flag_attribute_cxx(
+    file: &[u8],
+    offset: u32,
+) -> ffi::BooleanFlagAttributeQueryCXX {
+    ffi::BooleanFlagAttributeQueryCXX::new(find_boolean_flag_attribute(file, offset))
+}
+
 /// Get storage version number cc interlop
 pub fn get_storage_file_version_cxx(file_path: &str) -> ffi::VersionNumberQueryCXX {
     ffi::VersionNumberQueryCXX::new(get_storage_file_version(file_path))
@@ -315,12 +369,14 @@
     use crate::mapped_file::get_mapped_file;
     use crate::test_utils::copy_to_temp_file;
     use aconfig_storage_file::protos::storage_record_pb::write_proto_to_temp_file;
+    use aconfig_storage_file::{FlagInfoBit, StoredFlagType};
     use tempfile::NamedTempFile;
 
-    fn create_test_storage_files() -> [NamedTempFile; 4] {
+    fn create_test_storage_files() -> [NamedTempFile; 5] {
         let package_map = copy_to_temp_file("./tests/package.map").unwrap();
         let flag_map = copy_to_temp_file("./tests/flag.map").unwrap();
         let flag_val = copy_to_temp_file("./tests/flag.val").unwrap();
+        let flag_info = copy_to_temp_file("./tests/flag.info").unwrap();
 
         let text_proto = format!(
             r#"
@@ -330,21 +386,23 @@
     package_map: "{}"
     flag_map: "{}"
     flag_val: "{}"
+    flag_info: "{}"
     timestamp: 12345
 }}
 "#,
             package_map.path().display(),
             flag_map.path().display(),
-            flag_val.path().display()
+            flag_val.path().display(),
+            flag_info.path().display()
         );
         let pb_file = write_proto_to_temp_file(&text_proto).unwrap();
-        [package_map, flag_map, flag_val, pb_file]
+        [package_map, flag_map, flag_val, flag_info, pb_file]
     }
 
     #[test]
     // this test point locks down flag package offset query
     fn test_package_offset_query() {
-        let [_package_map, _flag_map, _flag_val, pb_file] = create_test_storage_files();
+        let [_package_map, _flag_map, _flag_val, _flag_info, pb_file] = create_test_storage_files();
         let pb_file_path = pb_file.path().display().to_string();
         let package_mapped_file = unsafe {
             get_mapped_file(&pb_file_path, "mockup", StorageFileType::PackageMap).unwrap()
@@ -375,32 +433,33 @@
     #[test]
     // this test point locks down flag offset query
     fn test_flag_offset_query() {
-        let [_package_map, _flag_map, _flag_val, pb_file] = create_test_storage_files();
+        let [_package_map, _flag_map, _flag_val, _flag_info, pb_file] = create_test_storage_files();
         let pb_file_path = pb_file.path().display().to_string();
         let flag_mapped_file =
             unsafe { get_mapped_file(&pb_file_path, "mockup", StorageFileType::FlagMap).unwrap() };
 
         let baseline = vec![
-            (0, "enabled_ro", 1u16),
-            (0, "enabled_rw", 2u16),
-            (1, "disabled_ro", 0u16),
-            (2, "enabled_ro", 1u16),
-            (1, "enabled_fixed_ro", 1u16),
-            (1, "enabled_ro", 2u16),
-            (2, "enabled_fixed_ro", 0u16),
-            (0, "disabled_rw", 0u16),
+            (0, "enabled_ro", StoredFlagType::ReadOnlyBoolean, 1u16),
+            (0, "enabled_rw", StoredFlagType::ReadWriteBoolean, 2u16),
+            (1, "disabled_ro", StoredFlagType::ReadOnlyBoolean, 0u16),
+            (2, "enabled_ro", StoredFlagType::ReadOnlyBoolean, 1u16),
+            (1, "enabled_fixed_ro", StoredFlagType::FixedReadOnlyBoolean, 1u16),
+            (1, "enabled_ro", StoredFlagType::ReadOnlyBoolean, 2u16),
+            (2, "enabled_fixed_ro", StoredFlagType::FixedReadOnlyBoolean, 0u16),
+            (0, "disabled_rw", StoredFlagType::ReadWriteBoolean, 0u16),
         ];
-        for (package_id, flag_name, expected_offset) in baseline.into_iter() {
+        for (package_id, flag_name, flag_type, flag_id) in baseline.into_iter() {
             let flag_offset =
                 get_flag_offset(&flag_mapped_file, package_id, flag_name).unwrap().unwrap();
-            assert_eq!(flag_offset, expected_offset);
+            assert_eq!(flag_offset.flag_type, flag_type);
+            assert_eq!(flag_offset.flag_id, flag_id);
         }
     }
 
     #[test]
-    // this test point locks down flag offset query
+    // this test point locks down flag value query
     fn test_flag_value_query() {
-        let [_package_map, _flag_map, _flag_val, pb_file] = create_test_storage_files();
+        let [_package_map, _flag_map, _flag_val, _flag_info, pb_file] = create_test_storage_files();
         let pb_file_path = pb_file.path().display().to_string();
         let flag_value_file =
             unsafe { get_mapped_file(&pb_file_path, "mockup", StorageFileType::FlagVal).unwrap() };
@@ -412,10 +471,27 @@
     }
 
     #[test]
+    // this test point locks donw flag info query
+    fn test_flag_info_query() {
+        let [_package_map, _flag_map, _flag_val, _flag_info, pb_file] = create_test_storage_files();
+        let pb_file_path = pb_file.path().display().to_string();
+        let flag_info_file =
+            unsafe { get_mapped_file(&pb_file_path, "mockup", StorageFileType::FlagInfo).unwrap() };
+        let is_rw: Vec<bool> = vec![true, false, true, false, false, false, false, false];
+        for (offset, expected_value) in is_rw.into_iter().enumerate() {
+            let attribute = get_boolean_flag_attribute(&flag_info_file, offset as u32).unwrap();
+            assert!((attribute & FlagInfoBit::IsSticky as u8) == 0u8);
+            assert_eq!((attribute & FlagInfoBit::IsReadWrite as u8) != 0u8, expected_value);
+            assert!((attribute & FlagInfoBit::HasOverride as u8) == 0u8);
+        }
+    }
+
+    #[test]
     // this test point locks down flag storage file version number query api
     fn test_storage_version_query() {
         assert_eq!(get_storage_file_version("./tests/package.map").unwrap(), 1);
         assert_eq!(get_storage_file_version("./tests/flag.map").unwrap(), 1);
         assert_eq!(get_storage_file_version("./tests/flag.val").unwrap(), 1);
+        assert_eq!(get_storage_file_version("./tests/flag.info").unwrap(), 1);
     }
 }
diff --git a/tools/aconfig/aconfig_storage_read_api/src/mapped_file.rs b/tools/aconfig/aconfig_storage_read_api/src/mapped_file.rs
index 51354db..9cc90ee 100644
--- a/tools/aconfig/aconfig_storage_read_api/src/mapped_file.rs
+++ b/tools/aconfig/aconfig_storage_read_api/src/mapped_file.rs
@@ -91,9 +91,7 @@
         StorageFileType::PackageMap => unsafe { map_file(files_location.package_map()) },
         StorageFileType::FlagMap => unsafe { map_file(files_location.flag_map()) },
         StorageFileType::FlagVal => unsafe { map_file(files_location.flag_val()) },
-        StorageFileType::FlagInfo => {
-            Err(MapFileFail(anyhow!("TODO: add support for flag info file")))
-        }
+        StorageFileType::FlagInfo => unsafe { map_file(files_location.flag_info()) },
     }
 }
 
diff --git a/tools/aconfig/aconfig_storage_read_api/tests/Android.bp b/tools/aconfig/aconfig_storage_read_api/tests/Android.bp
index d9cf238..6b05ca6 100644
--- a/tools/aconfig/aconfig_storage_read_api/tests/Android.bp
+++ b/tools/aconfig/aconfig_storage_read_api/tests/Android.bp
@@ -14,6 +14,7 @@
         "package.map",
         "flag.map",
         "flag.val",
+        "flag.info",
     ],
     test_suites: ["general-tests"],
 }
@@ -35,6 +36,7 @@
         "package.map",
         "flag.map",
         "flag.val",
+        "flag.info",
     ],
     test_suites: [
         "device-tests",
diff --git a/tools/aconfig/aconfig_storage_read_api/tests/flag.info b/tools/aconfig/aconfig_storage_read_api/tests/flag.info
new file mode 100644
index 0000000..820d839
--- /dev/null
+++ b/tools/aconfig/aconfig_storage_read_api/tests/flag.info
Binary files differ
diff --git a/tools/aconfig/aconfig_storage_read_api/tests/storage_read_api_test.cpp b/tools/aconfig/aconfig_storage_read_api/tests/storage_read_api_test.cpp
index 539474b..3fd0173 100644
--- a/tools/aconfig/aconfig_storage_read_api/tests/storage_read_api_test.cpp
+++ b/tools/aconfig/aconfig_storage_read_api/tests/storage_read_api_test.cpp
@@ -47,7 +47,8 @@
 
   Result<std::string> write_storage_location_pb_file(std::string const& package_map,
                                                      std::string const& flag_map,
-                                                     std::string const& flag_val) {
+                                                     std::string const& flag_val,
+                                                     std::string const& flag_info) {
     auto temp_file = std::tmpnam(nullptr);
     auto proto = storage_files();
     auto* info = proto.add_files();
@@ -56,6 +57,7 @@
     info->set_package_map(package_map);
     info->set_flag_map(flag_map);
     info->set_flag_val(flag_val);
+    info->set_flag_info(flag_info);
     info->set_timestamp(12345);
 
     auto content = std::string();
@@ -71,20 +73,23 @@
     package_map = *copy_to_temp_file(test_dir + "/package.map");
     flag_map = *copy_to_temp_file(test_dir + "/flag.map");
     flag_val = *copy_to_temp_file(test_dir + "/flag.val");
+    flag_info = *copy_to_temp_file(test_dir + "/flag.info");
     storage_record_pb = *write_storage_location_pb_file(
-        package_map, flag_map, flag_val);
+        package_map, flag_map, flag_val, flag_info);
   }
 
   void TearDown() override {
     std::remove(package_map.c_str());
     std::remove(flag_map.c_str());
     std::remove(flag_val.c_str());
+    std::remove(flag_info.c_str());
     std::remove(storage_record_pb.c_str());
   }
 
   std::string package_map;
   std::string flag_map;
   std::string flag_val;
+  std::string flag_info;
   std::string storage_record_pb;
 };
 
@@ -156,21 +161,22 @@
       storage_record_pb, "mockup", api::StorageFileType::flag_map);
   ASSERT_TRUE(mapped_file.ok());
 
-  auto baseline = std::vector<std::tuple<int, std::string, int>>{
-    {0, "enabled_ro", 1},
-    {0, "enabled_rw", 2},
-    {1, "disabled_ro", 0},
-    {2, "enabled_ro", 1},
-    {1, "enabled_fixed_ro", 1},
-    {1, "enabled_ro", 2},
-    {2, "enabled_fixed_ro", 0},
-    {0, "disabled_rw", 0},
+  auto baseline = std::vector<std::tuple<int, std::string, api::StoredFlagType, int>>{
+    {0, "enabled_ro", api::StoredFlagType::ReadOnlyBoolean, 1},
+    {0, "enabled_rw", api::StoredFlagType::ReadWriteBoolean, 2},
+    {1, "disabled_ro", api::StoredFlagType::ReadOnlyBoolean, 0},
+    {2, "enabled_ro", api::StoredFlagType::ReadOnlyBoolean, 1},
+    {1, "enabled_fixed_ro", api::StoredFlagType::FixedReadOnlyBoolean, 1},
+    {1, "enabled_ro", api::StoredFlagType::ReadOnlyBoolean, 2},
+    {2, "enabled_fixed_ro", api::StoredFlagType::FixedReadOnlyBoolean, 0},
+    {0, "disabled_rw", api::StoredFlagType::ReadWriteBoolean, 0},
   };
-  for (auto const&[package_id, flag_name, expected_offset] : baseline) {
+  for (auto const&[package_id, flag_name, flag_type, flag_id] : baseline) {
     auto offset = api::get_flag_offset(*mapped_file, package_id, flag_name);
     ASSERT_TRUE(offset.ok());
     ASSERT_TRUE(offset->flag_exists);
-    ASSERT_EQ(offset->flag_offset, expected_offset);
+    ASSERT_EQ(offset->flag_type, flag_type);
+    ASSERT_EQ(offset->flag_id, flag_id);
   }
 }
 
@@ -215,3 +221,33 @@
   ASSERT_EQ(value.error().message(),
             std::string("InvalidStorageFileOffset(Flag value offset goes beyond the end of the file.)"));
 }
+
+/// Test to lock down storage flag info query api
+TEST_F(AconfigStorageTest, test_boolean_flag_info_query) {
+  auto mapped_file = private_api::get_mapped_file_impl(
+      storage_record_pb, "mockup", api::StorageFileType::flag_info);
+  ASSERT_TRUE(mapped_file.ok());
+
+  auto expected_value = std::vector<bool>{
+    true, false, true, false, false, false, false, false};
+  for (int offset = 0; offset < 8; ++offset) {
+    auto attribute = api::get_boolean_flag_attribute(*mapped_file, offset);
+    ASSERT_TRUE(attribute.ok());
+    ASSERT_EQ(*attribute & static_cast<uint8_t>(api::FlagInfoBit::IsSticky), 0);
+    ASSERT_EQ((*attribute & static_cast<uint8_t>(api::FlagInfoBit::IsReadWrite)) != 0,
+              expected_value[offset]);
+    ASSERT_EQ(*attribute & static_cast<uint8_t>(api::FlagInfoBit::HasOverride), 0);
+  }
+}
+
+/// Negative test to lock down the error when querying flag info out of range
+TEST_F(AconfigStorageTest, test_invalid_boolean_flag_info_query) {
+  auto mapped_file = private_api::get_mapped_file_impl(
+      storage_record_pb, "mockup", api::StorageFileType::flag_info);
+  ASSERT_TRUE(mapped_file.ok());
+
+  auto attribute = api::get_boolean_flag_attribute(*mapped_file, 8);
+  ASSERT_FALSE(attribute.ok());
+  ASSERT_EQ(attribute.error().message(),
+            std::string("InvalidStorageFileOffset(Flag info offset goes beyond the end of the file.)"));
+}
diff --git a/tools/aconfig/aconfig_storage_read_api/tests/storage_read_api_test.rs b/tools/aconfig/aconfig_storage_read_api/tests/storage_read_api_test.rs
index 7687d0f..21caead 100644
--- a/tools/aconfig/aconfig_storage_read_api/tests/storage_read_api_test.rs
+++ b/tools/aconfig/aconfig_storage_read_api/tests/storage_read_api_test.rs
@@ -1,10 +1,10 @@
 #[cfg(not(feature = "cargo"))]
 mod aconfig_storage_rust_test {
     use aconfig_storage_file::protos::storage_record_pb::write_proto_to_temp_file;
-    use aconfig_storage_file::StorageFileType;
+    use aconfig_storage_file::{FlagInfoBit, StorageFileType, StoredFlagType};
     use aconfig_storage_read_api::{
-        get_boolean_flag_value, get_flag_offset, get_package_offset, get_storage_file_version,
-        mapped_file::get_mapped_file, PackageOffset,
+        get_boolean_flag_attribute, get_boolean_flag_value, get_flag_offset, get_package_offset,
+        get_storage_file_version, mapped_file::get_mapped_file, PackageOffset,
     };
     use std::fs;
     use tempfile::NamedTempFile;
@@ -15,10 +15,11 @@
         file
     }
 
-    fn create_test_storage_files() -> [NamedTempFile; 4] {
+    fn create_test_storage_files() -> [NamedTempFile; 5] {
         let package_map = copy_to_temp_file("./package.map");
         let flag_map = copy_to_temp_file("./flag.map");
         let flag_val = copy_to_temp_file("./flag.val");
+        let flag_info = copy_to_temp_file("./flag.info");
 
         let text_proto = format!(
             r#"
@@ -28,20 +29,22 @@
     package_map: "{}"
     flag_map: "{}"
     flag_val: "{}"
+    flag_info: "{}"
     timestamp: 12345
 }}
 "#,
             package_map.path().display(),
             flag_map.path().display(),
-            flag_val.path().display()
+            flag_val.path().display(),
+            flag_info.path().display()
         );
         let pb_file = write_proto_to_temp_file(&text_proto).unwrap();
-        [package_map, flag_map, flag_val, pb_file]
+        [package_map, flag_map, flag_val, flag_info, pb_file]
     }
 
     #[test]
     fn test_unavailable_stoarge() {
-        let [_package_map, _flag_map, _flag_val, pb_file] = create_test_storage_files();
+        let [_package_map, _flag_map, _flag_val, _flag_info, pb_file] = create_test_storage_files();
         let pb_file_path = pb_file.path().display().to_string();
         // SAFETY:
         // The safety here is ensured as the test process will not write to temp storage file
@@ -56,7 +59,7 @@
 
     #[test]
     fn test_package_offset_query() {
-        let [_package_map, _flag_map, _flag_val, pb_file] = create_test_storage_files();
+        let [_package_map, _flag_map, _flag_val, _flag_info, pb_file] = create_test_storage_files();
         let pb_file_path = pb_file.path().display().to_string();
         // SAFETY:
         // The safety here is ensured as the test process will not write to temp storage file
@@ -88,7 +91,7 @@
 
     #[test]
     fn test_none_exist_package_offset_query() {
-        let [_package_map, _flag_map, _flag_val, pb_file] = create_test_storage_files();
+        let [_package_map, _flag_map, _flag_val, _flag_info, pb_file] = create_test_storage_files();
         let pb_file_path = pb_file.path().display().to_string();
         // SAFETY:
         // The safety here is ensured as the test process will not write to temp storage file
@@ -103,7 +106,7 @@
 
     #[test]
     fn test_flag_offset_query() {
-        let [_package_map, _flag_map, _flag_val, pb_file] = create_test_storage_files();
+        let [_package_map, _flag_map, _flag_val, _flag_info, pb_file] = create_test_storage_files();
         let pb_file_path = pb_file.path().display().to_string();
         // SAFETY:
         // The safety here is ensured as the test process will not write to temp storage file
@@ -111,25 +114,26 @@
             unsafe { get_mapped_file(&pb_file_path, "mockup", StorageFileType::FlagMap).unwrap() };
 
         let baseline = vec![
-            (0, "enabled_ro", 1u16),
-            (0, "enabled_rw", 2u16),
-            (1, "disabled_ro", 0u16),
-            (2, "enabled_ro", 1u16),
-            (1, "enabled_fixed_ro", 1u16),
-            (1, "enabled_ro", 2u16),
-            (2, "enabled_fixed_ro", 0u16),
-            (0, "disabled_rw", 0u16),
+            (0, "enabled_ro", StoredFlagType::ReadOnlyBoolean, 1u16),
+            (0, "enabled_rw", StoredFlagType::ReadWriteBoolean, 2u16),
+            (1, "disabled_ro", StoredFlagType::ReadOnlyBoolean, 0u16),
+            (2, "enabled_ro", StoredFlagType::ReadOnlyBoolean, 1u16),
+            (1, "enabled_fixed_ro", StoredFlagType::FixedReadOnlyBoolean, 1u16),
+            (1, "enabled_ro", StoredFlagType::ReadOnlyBoolean, 2u16),
+            (2, "enabled_fixed_ro", StoredFlagType::FixedReadOnlyBoolean, 0u16),
+            (0, "disabled_rw", StoredFlagType::ReadWriteBoolean, 0u16),
         ];
-        for (package_id, flag_name, expected_offset) in baseline.into_iter() {
+        for (package_id, flag_name, flag_type, flag_id) in baseline.into_iter() {
             let flag_offset =
                 get_flag_offset(&flag_mapped_file, package_id, flag_name).unwrap().unwrap();
-            assert_eq!(flag_offset, expected_offset);
+            assert_eq!(flag_offset.flag_type, flag_type);
+            assert_eq!(flag_offset.flag_id, flag_id);
         }
     }
 
     #[test]
     fn test_none_exist_flag_offset_query() {
-        let [_package_map, _flag_map, _flag_val, pb_file] = create_test_storage_files();
+        let [_package_map, _flag_map, _flag_val, _flag_info, pb_file] = create_test_storage_files();
         let pb_file_path = pb_file.path().display().to_string();
         // SAFETY:
         // The safety here is ensured as the test process will not write to temp storage file
@@ -144,7 +148,7 @@
 
     #[test]
     fn test_boolean_flag_value_query() {
-        let [_package_map, _flag_map, _flag_val, pb_file] = create_test_storage_files();
+        let [_package_map, _flag_map, _flag_val, _flag_info, pb_file] = create_test_storage_files();
         let pb_file_path = pb_file.path().display().to_string();
         // SAFETY:
         // The safety here is ensured as the test process will not write to temp storage file
@@ -159,7 +163,7 @@
 
     #[test]
     fn test_invalid_boolean_flag_value_query() {
-        let [_package_map, _flag_map, _flag_val, pb_file] = create_test_storage_files();
+        let [_package_map, _flag_map, _flag_val, _flag_info, pb_file] = create_test_storage_files();
         let pb_file_path = pb_file.path().display().to_string();
         // SAFETY:
         // The safety here is ensured as the test process will not write to temp storage file
@@ -173,9 +177,42 @@
     }
 
     #[test]
+    fn test_flag_info_query() {
+        let [_package_map, _flag_map, _flag_val, _flag_info, pb_file] = create_test_storage_files();
+        let pb_file_path = pb_file.path().display().to_string();
+        // SAFETY:
+        // The safety here is ensured as the test process will not write to temp storage file
+        let flag_info_file =
+            unsafe { get_mapped_file(&pb_file_path, "mockup", StorageFileType::FlagInfo).unwrap() };
+        let is_rw: Vec<bool> = vec![true, false, true, false, false, false, false, false];
+        for (offset, expected_value) in is_rw.into_iter().enumerate() {
+            let attribute = get_boolean_flag_attribute(&flag_info_file, offset as u32).unwrap();
+            assert!((attribute & FlagInfoBit::IsSticky as u8) == 0u8);
+            assert_eq!((attribute & FlagInfoBit::IsReadWrite as u8) != 0u8, expected_value);
+            assert!((attribute & FlagInfoBit::HasOverride as u8) == 0u8);
+        }
+    }
+
+    #[test]
+    fn test_invalid_boolean_flag_info_query() {
+        let [_package_map, _flag_map, _flag_val, _flag_info, pb_file] = create_test_storage_files();
+        let pb_file_path = pb_file.path().display().to_string();
+        // SAFETY:
+        // The safety here is ensured as the test process will not write to temp storage file
+        let flag_info_file =
+            unsafe { get_mapped_file(&pb_file_path, "mockup", StorageFileType::FlagInfo).unwrap() };
+        let err = get_boolean_flag_attribute(&flag_info_file, 8u32).unwrap_err();
+        assert_eq!(
+            format!("{:?}", err),
+            "InvalidStorageFileOffset(Flag info offset goes beyond the end of the file.)"
+        );
+    }
+
+    #[test]
     fn test_storage_version_query() {
         assert_eq!(get_storage_file_version("./package.map").unwrap(), 1);
         assert_eq!(get_storage_file_version("./flag.map").unwrap(), 1);
         assert_eq!(get_storage_file_version("./flag.val").unwrap(), 1);
+        assert_eq!(get_storage_file_version("./flag.info").unwrap(), 1);
     }
 }
diff --git a/tools/aconfig/aconfig_storage_write_api/aconfig_storage_write_api.cpp b/tools/aconfig/aconfig_storage_write_api/aconfig_storage_write_api.cpp
index e5155a4..ea88f05 100644
--- a/tools/aconfig/aconfig_storage_write_api/aconfig_storage_write_api.cpp
+++ b/tools/aconfig/aconfig_storage_write_api/aconfig_storage_write_api.cpp
@@ -126,4 +126,18 @@
   return {};
 }
 
+Result<void> create_flag_info(
+    std::string const& package_map,
+    std::string const& flag_map,
+    std::string const& flag_info_out) {
+  auto creation_cxx = create_flag_info_cxx(
+      rust::Str(package_map.c_str()),
+      rust::Str(flag_map.c_str()),
+      rust::Str(flag_info_out.c_str()));
+  if (creation_cxx.success) {
+    return {};
+  } else {
+    return android::base::Error() << creation_cxx.error_message;
+  }
+}
 } // namespace aconfig_storage
diff --git a/tools/aconfig/aconfig_storage_write_api/include/aconfig_storage/aconfig_storage_write_api.hpp b/tools/aconfig/aconfig_storage_write_api/include/aconfig_storage/aconfig_storage_write_api.hpp
index 9e6332a..b652510 100644
--- a/tools/aconfig/aconfig_storage_write_api/include/aconfig_storage/aconfig_storage_write_api.hpp
+++ b/tools/aconfig/aconfig_storage_write_api/include/aconfig_storage/aconfig_storage_write_api.hpp
@@ -34,4 +34,13 @@
     uint32_t offset,
     bool value);
 
+/// Create flag info file based on package and flag map
+/// \input package_map: package map file
+/// \input flag_map: flag map file
+/// \input flag_info_out: flag info file to be created
+Result<void> create_flag_info(
+    std::string const& package_map,
+    std::string const& flag_map,
+    std::string const& flag_info_out);
+
 } // namespace aconfig_storage
diff --git a/tools/aconfig/aconfig_storage_write_api/src/lib.rs b/tools/aconfig/aconfig_storage_write_api/src/lib.rs
index 5562d6a..678bbd5 100644
--- a/tools/aconfig/aconfig_storage_write_api/src/lib.rs
+++ b/tools/aconfig/aconfig_storage_write_api/src/lib.rs
@@ -23,10 +23,15 @@
 #[cfg(test)]
 mod test_utils;
 
-use aconfig_storage_file::AconfigStorageError;
+use aconfig_storage_file::{
+    AconfigStorageError, FlagInfoHeader, FlagInfoList, FlagInfoNode, FlagTable, PackageTable,
+    StorageFileType, StoredFlagType, FILE_VERSION,
+};
 
 use anyhow::anyhow;
 use memmap2::MmapMut;
+use std::fs::File;
+use std::io::{Read, Write};
 
 /// Storage file location pb file
 pub const STORAGE_LOCATION_FILE: &str = "/metadata/aconfig/persistent_storage_file_records.pb";
@@ -65,6 +70,86 @@
     })
 }
 
+/// Read in storage file as bytes
+fn read_file_to_bytes(file_path: &str) -> Result<Vec<u8>, AconfigStorageError> {
+    let mut file = File::open(file_path).map_err(|errmsg| {
+        AconfigStorageError::FileReadFail(anyhow!("Failed to open file {}: {}", file_path, errmsg))
+    })?;
+    let mut buffer = Vec::new();
+    file.read_to_end(&mut buffer).map_err(|errmsg| {
+        AconfigStorageError::FileReadFail(anyhow!(
+            "Failed to read bytes from file {}: {}",
+            file_path,
+            errmsg
+        ))
+    })?;
+    Ok(buffer)
+}
+
+/// Create flag info file given package map file and flag map file
+/// \input package_map: package map file
+/// \input flag_map: flag map file
+/// \output flag_info_out: created flag info file
+pub fn create_flag_info(
+    package_map: &str,
+    flag_map: &str,
+    flag_info_out: &str,
+) -> Result<(), AconfigStorageError> {
+    let package_table = PackageTable::from_bytes(&read_file_to_bytes(package_map)?)?;
+    let flag_table = FlagTable::from_bytes(&read_file_to_bytes(flag_map)?)?;
+
+    if package_table.header.container != flag_table.header.container {
+        return Err(AconfigStorageError::FileCreationFail(anyhow!(
+            "container for package map {} and flag map {} does not match",
+            package_table.header.container,
+            flag_table.header.container,
+        )));
+    }
+
+    let mut package_offsets = vec![0; package_table.header.num_packages as usize];
+    for node in package_table.nodes.iter() {
+        package_offsets[node.package_id as usize] = node.boolean_offset;
+    }
+
+    let mut is_flag_rw = vec![false; flag_table.header.num_flags as usize];
+    for node in flag_table.nodes.iter() {
+        let flag_offset = package_offsets[node.package_id as usize] + node.flag_id as u32;
+        is_flag_rw[flag_offset as usize] = node.flag_type == StoredFlagType::ReadWriteBoolean;
+    }
+
+    let mut list = FlagInfoList {
+        header: FlagInfoHeader {
+            version: FILE_VERSION,
+            container: flag_table.header.container,
+            file_type: StorageFileType::FlagInfo as u8,
+            file_size: 0,
+            num_flags: flag_table.header.num_flags,
+            boolean_flag_offset: 0,
+        },
+        nodes: is_flag_rw.iter().map(|&rw| FlagInfoNode::create(rw)).collect(),
+    };
+
+    list.header.boolean_flag_offset = list.header.into_bytes().len() as u32;
+    list.header.file_size = list.into_bytes().len() as u32;
+
+    let mut file = File::create(flag_info_out).map_err(|errmsg| {
+        AconfigStorageError::FileCreationFail(anyhow!(
+            "fail to create file {}: {}",
+            flag_info_out,
+            errmsg
+        ))
+    })?;
+    file.write_all(&list.into_bytes()).map_err(|errmsg| {
+        AconfigStorageError::FileCreationFail(anyhow!(
+            "fail to write to file {}: {}",
+            flag_info_out,
+            errmsg
+        ))
+    })?;
+
+    Ok(())
+}
+
 // *************************************** //
 // CC INTERLOP
 // *************************************** //
@@ -78,6 +163,12 @@
         pub error_message: String,
     }
 
+    // Flag info file creation return for cc interlop
+    pub struct FlagInfoCreationCXX {
+        pub success: bool,
+        pub error_message: String,
+    }
+
     // Rust export to c++
     extern "Rust" {
         pub fn update_boolean_flag_value_cxx(
@@ -85,6 +176,12 @@
             offset: u32,
             value: bool,
         ) -> BooleanFlagValueUpdateCXX;
+
+        pub fn create_flag_info_cxx(
+            package_map: &str,
+            flag_map: &str,
+            flag_info_out: &str,
+        ) -> FlagInfoCreationCXX;
     }
 }
 
@@ -104,14 +201,33 @@
     }
 }
 
+/// Create flag info file cc interlop
+pub(crate) fn create_flag_info_cxx(
+    package_map: &str,
+    flag_map: &str,
+    flag_info_out: &str,
+) -> ffi::FlagInfoCreationCXX {
+    match create_flag_info(package_map, flag_map, flag_info_out) {
+        Ok(()) => ffi::FlagInfoCreationCXX { success: true, error_message: String::from("") },
+        Err(errmsg) => {
+            ffi::FlagInfoCreationCXX { success: false, error_message: format!("{:?}", errmsg) }
+        }
+    }
+}
+
 #[cfg(test)]
 mod tests {
     use super::*;
     use crate::test_utils::copy_to_temp_file;
     use aconfig_storage_file::protos::storage_record_pb::write_proto_to_temp_file;
+    use aconfig_storage_file::test_utils::{
+        create_test_flag_info_list, create_test_flag_table, create_test_package_table,
+        write_bytes_to_temp_file,
+    };
     use aconfig_storage_read_api::flag_value_query::find_boolean_flag_value;
     use std::fs::File;
     use std::io::Read;
+    use tempfile::NamedTempFile;
 
     fn get_boolean_flag_value_at_offset(file: &str, offset: u32) -> bool {
         let mut f = File::open(&file).unwrap();
@@ -156,4 +272,31 @@
             }
         }
     }
+
+    fn create_empty_temp_file() -> Result<NamedTempFile, AconfigStorageError> {
+        let file = NamedTempFile::new().map_err(|_| {
+            AconfigStorageError::FileCreationFail(anyhow!("Failed to create temp file"))
+        })?;
+        Ok(file)
+    }
+
+    #[test]
+    // this test point locks down the flag info creation
+    fn test_create_flag_info() {
+        let package_table =
+            write_bytes_to_temp_file(&create_test_package_table().into_bytes()).unwrap();
+        let flag_table = write_bytes_to_temp_file(&create_test_flag_table().into_bytes()).unwrap();
+        let flag_info = create_empty_temp_file().unwrap();
+
+        let package_table_path = package_table.path().display().to_string();
+        let flag_table_path = flag_table.path().display().to_string();
+        let flag_info_path = flag_info.path().display().to_string();
+
+        assert!(create_flag_info(&package_table_path, &flag_table_path, &flag_info_path).is_ok());
+
+        let flag_info =
+            FlagInfoList::from_bytes(&read_file_to_bytes(&flag_info_path).unwrap()).unwrap();
+        let expected_flag_info = create_test_flag_info_list();
+        assert_eq!(flag_info, expected_flag_info);
+    }
 }
diff --git a/tools/aconfig/aconfig_storage_write_api/tests/Android.bp b/tools/aconfig/aconfig_storage_write_api/tests/Android.bp
index d2a52fe..5b23dbc 100644
--- a/tools/aconfig/aconfig_storage_write_api/tests/Android.bp
+++ b/tools/aconfig/aconfig_storage_write_api/tests/Android.bp
@@ -39,4 +39,5 @@
         "device-tests",
         "general-tests",
     ],
+    ldflags: ["-Wl,--allow-multiple-definition"],
 }
diff --git a/tools/finalization/build-step-1-and-m.sh b/tools/finalization/build-step-1-and-m.sh
index 0e7129f..88bb347 100755
--- a/tools/finalization/build-step-1-and-m.sh
+++ b/tools/finalization/build-step-1-and-m.sh
@@ -9,10 +9,9 @@
     local m="$top/build/soong/soong_ui.bash --make-mode TARGET_PRODUCT=aosp_arm64 TARGET_BUILD_VARIANT=userdebug"
 
     # This command tests:
-    #   The release state for AIDL.
     #   ABI difference between user and userdebug builds.
     #   Resource/SDK finalization.
-    AIDL_FROZEN_REL=true $m
+    $m
 }
 
 finalize_main_step1_and_m
diff --git a/tools/finalization/command-line-options.sh b/tools/finalization/command-line-options.sh
index 1c5df46..d9397c2 100644
--- a/tools/finalization/command-line-options.sh
+++ b/tools/finalization/command-line-options.sh
@@ -2,7 +2,7 @@
 eval set -- "$ARGV"
 while true; do
     case "$1" in
-        --dry-run) repo_upload_dry_run_arg="--dry-run"; shift ;;
+        --dry-run) repo_upload_dry_run_arg="--dry-run"; repo_branch="finalization-dry-run"; shift ;;
         *) break
     esac
 done
diff --git a/tools/finalization/dryrun-step-1-and-2.sh b/tools/finalization/dryrun-step-1-and-2.sh
index 38fdb05..f883bca 100755
--- a/tools/finalization/dryrun-step-1-and-2.sh
+++ b/tools/finalization/dryrun-step-1-and-2.sh
@@ -30,10 +30,10 @@
 
     # build to confirm everything is OK
     local m_next="$top/build/soong/soong_ui.bash --make-mode TARGET_RELEASE=next TARGET_PRODUCT=aosp_arm64 TARGET_BUILD_VARIANT=userdebug"
-    AIDL_FROZEN_REL=true $m_next
+    $m_next
 
     local m_fina="$top/build/soong/soong_ui.bash --make-mode TARGET_RELEASE=fina_2 TARGET_PRODUCT=aosp_arm64 TARGET_BUILD_VARIANT=userdebug"
-    AIDL_FROZEN_REL=true $m_fina
+    $m_fina
 }
 
 finalize_step_2_main
diff --git a/tools/finalization/dryrun-step-1.sh b/tools/finalization/dryrun-step-1.sh
index d889395..0f2bc63 100755
--- a/tools/finalization/dryrun-step-1.sh
+++ b/tools/finalization/dryrun-step-1.sh
@@ -26,10 +26,10 @@
 
     # build to confirm everything is OK
     local m_next="$top/build/soong/soong_ui.bash --make-mode TARGET_RELEASE=next TARGET_PRODUCT=aosp_arm64 TARGET_BUILD_VARIANT=userdebug"
-    AIDL_FROZEN_REL=true $m_next
+    $m_next
 
     local m_fina="$top/build/soong/soong_ui.bash --make-mode TARGET_RELEASE=fina_1 TARGET_PRODUCT=aosp_arm64 TARGET_BUILD_VARIANT=userdebug"
-    AIDL_FROZEN_REL=true $m_fina
+    $m_fina
 }
 
 finalize_step_1_main
diff --git a/tools/finalization/finalize-sdk-resources.sh b/tools/finalization/finalize-sdk-resources.sh
index 003b7c0..10266ed 100755
--- a/tools/finalization/finalize-sdk-resources.sh
+++ b/tools/finalization/finalize-sdk-resources.sh
@@ -120,10 +120,10 @@
     local build_tools_source="$top/development/sdk/build_tools_source.prop_template"
     sed -i -e 's/Pkg\.Revision.*/Pkg\.Revision=${PLATFORM_SDK_VERSION}.0.0/g' $build_tools_source
 
-    # build/bazel
-    local codename_version="\"${FINAL_PLATFORM_CODENAME}\": ${FINAL_PLATFORM_SDK_VERSION}"
-    if ! grep -q "$codename_version" "$top/build/bazel/rules/common/api_constants.bzl" ; then
-        sed -i -e "/:.*$((${FINAL_PLATFORM_SDK_VERSION}-1)),/a \\    $codename_version," "$top/build/bazel/rules/common/api_constants.bzl"
+    # build/soong
+    local codename_version="\"${FINAL_PLATFORM_CODENAME}\":     ${FINAL_PLATFORM_SDK_VERSION}"
+    if ! grep -q "$codename_version" "$top/build/soong/android/api_levels.go" ; then
+        sed -i -e "/:.*$((${FINAL_PLATFORM_SDK_VERSION}-1)),/a \\\t\t$codename_version," "$top/build/soong/android/api_levels.go"
     fi
 
     # cts
diff --git a/tools/finalization/step-0.sh b/tools/finalization/step-0.sh
index 8da866c..2087f6e 100755
--- a/tools/finalization/step-0.sh
+++ b/tools/finalization/step-0.sh
@@ -9,7 +9,7 @@
     set +e
     repo forall -c '\
         if [[ $(git status --short) ]]; then
-            repo start "VINTF-$FINAL_BOARD_API_LEVEL-Finalization" ;
+            repo start "'$repo_branch'" ;
             git add -A . ;
             git commit -m "Vendor API level $FINAL_BOARD_API_LEVEL is now frozen" \
                        -m "Ignore-AOSP-First: VINTF $FINAL_BOARD_API_LEVEL Finalization
@@ -21,8 +21,9 @@
 
 function finalize_step_0_main() {
     local top="$(dirname "$0")"/../../../..
-    source $top/build/make/tools/finalization/command-line-options.sh
     source $top/build/make/tools/finalization/environment.sh
+    local repo_branch="VINTF-$FINAL_BOARD_API_LEVEL-Finalization"
+    source $top/build/make/tools/finalization/command-line-options.sh
 
     local m="$top/build/soong/soong_ui.bash --make-mode TARGET_RELEASE=next TARGET_PRODUCT=aosp_arm64 TARGET_BUILD_VARIANT=userdebug"
 
diff --git a/tools/finalization/step-1.sh b/tools/finalization/step-1.sh
index ea947b9..736d641 100755
--- a/tools/finalization/step-1.sh
+++ b/tools/finalization/step-1.sh
@@ -7,7 +7,7 @@
     set +e
     repo forall -c '\
         if [[ $(git status --short) ]]; then
-            repo start "$FINAL_PLATFORM_CODENAME-SDK-Finalization" ;
+            repo start "'$repo_branch'" ;
             git add -A . ;
             git commit -m "$FINAL_PLATFORM_CODENAME is now $FINAL_PLATFORM_SDK_VERSION and extension version $FINAL_MAINLINE_EXTENSION" \
                        -m "Ignore-AOSP-First: $FINAL_PLATFORM_CODENAME Finalization
@@ -19,8 +19,9 @@
 
 function finalize_step_1_main() {
     local top="$(dirname "$0")"/../../../..
-    source $top/build/make/tools/finalization/command-line-options.sh
     source $top/build/make/tools/finalization/environment.sh
+    local repo_branch="$FINAL_PLATFORM_CODENAME-SDK-Finalization"
+    source $top/build/make/tools/finalization/command-line-options.sh
 
     source $top/build/make/tools/finalization/finalize-sdk-resources.sh
 
@@ -29,10 +30,10 @@
 
     # build to confirm everything is OK
     local m_next="$top/build/soong/soong_ui.bash --make-mode TARGET_RELEASE=next TARGET_PRODUCT=aosp_arm64 TARGET_BUILD_VARIANT=userdebug"
-    AIDL_FROZEN_REL=true $m_next
+    $m_next
 
     local m_fina="$top/build/soong/soong_ui.bash --make-mode TARGET_RELEASE=fina_1 TARGET_PRODUCT=aosp_arm64 TARGET_BUILD_VARIANT=userdebug"
-    AIDL_FROZEN_REL=true $m_fina
+    $m_fina
 }
 
 finalize_step_1_main $@
diff --git a/tools/finalization/step-2.sh b/tools/finalization/step-2.sh
index d07989e..52e3887 100755
--- a/tools/finalization/step-2.sh
+++ b/tools/finalization/step-2.sh
@@ -4,7 +4,7 @@
 function commit_step_2_changes() {
     repo forall -c '\
         if [[ $(git status --short) ]]; then
-            repo start "$FINAL_PLATFORM_CODENAME-SDK-Finalization-Rel" ;
+            repo start "'$repo_branch'" ;
             git add -A . ;
             git commit -m "$FINAL_PLATFORM_CODENAME/$FINAL_PLATFORM_SDK_VERSION is now REL" \
                        -m "Ignore-AOSP-First: $FINAL_PLATFORM_CODENAME Finalization
@@ -17,8 +17,9 @@
 
 function finalize_step_2_main() {
     local top="$(dirname "$0")"/../../../..
-    source $top/build/make/tools/finalization/command-line-options.sh
     source $top/build/make/tools/finalization/environment.sh
+    local repo_branch="$FINAL_PLATFORM_CODENAME-SDK-Finalization-Rel"
+    source $top/build/make/tools/finalization/command-line-options.sh
 
     # prebuilts etc
     source $top/build/make/tools/finalization/finalize-sdk-rel.sh
@@ -28,10 +29,10 @@
 
     # build to confirm everything is OK
     local m_next="$top/build/soong/soong_ui.bash --make-mode TARGET_RELEASE=next TARGET_PRODUCT=aosp_arm64 TARGET_BUILD_VARIANT=userdebug"
-    AIDL_FROZEN_REL=true $m_next
+    $m_next
 
     local m_fina="$top/build/soong/soong_ui.bash --make-mode TARGET_RELEASE=fina_2 TARGET_PRODUCT=aosp_arm64 TARGET_BUILD_VARIANT=userdebug"
-    AIDL_FROZEN_REL=true $m_fina
+    $m_fina
 }
 
 finalize_step_2_main $@
diff --git a/tools/releasetools/Android.bp b/tools/releasetools/Android.bp
index 4941c71..9385f0c 100644
--- a/tools/releasetools/Android.bp
+++ b/tools/releasetools/Android.bp
@@ -244,7 +244,6 @@
         "boot_signer",
         "brotli",
         "bsdiff",
-        "imgdiff",
         "lz4",
         "mkbootfs",
         "signapk",
@@ -308,7 +307,6 @@
         "brotli",
         "bsdiff",
         "deapexer",
-        "imgdiff",
         "lz4",
         "mkbootfs",
         "signapk",
diff --git a/tools/releasetools/common.py b/tools/releasetools/common.py
index 8836248..264c2d8 100644
--- a/tools/releasetools/common.py
+++ b/tools/releasetools/common.py
@@ -955,6 +955,13 @@
   d["build.prop"] = d["system.build.prop"]
 
   if d.get("avb_enable") == "true":
+    build_info = BuildInfo(d, use_legacy_id=True)
+    # Set up the salt for partitions without build.prop
+    if build_info.fingerprint:
+      if "fingerprint" not in d:
+        d["fingerprint"] = build_info.fingerprint
+      if "avb_salt" not in d:
+        d["avb_salt"] = sha256(build_info.fingerprint.encode()).hexdigest()
     # Set the vbmeta digest if exists
     try:
       d["vbmeta_digest"] = read_helper("META/vbmeta_digest.txt").rstrip()