Merge "Convert BuildIgnoreApexContritbutions variable to a boolean" into main
diff --git a/core/OWNERS b/core/OWNERS
index 36951a9..1c3d017 100644
--- a/core/OWNERS
+++ b/core/OWNERS
@@ -10,3 +10,6 @@
 
 # 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/board_config.mk b/core/board_config.mk
index 4424517..633303f 100644
--- a/core/board_config.mk
+++ b/core/board_config.mk
@@ -992,7 +992,7 @@
 # BOARD_API_LEVEL for vendor API surface
 ifdef RELEASE_BOARD_API_LEVEL
   ifdef BOARD_API_LEVEL
-    $(error BOARD_API_LEVEL must not set manully. The build system automatically sets this value.)
+    $(error BOARD_API_LEVEL must not be set manually. The build system automatically sets this value.)
   endif
   BOARD_API_LEVEL := $(RELEASE_BOARD_API_LEVEL)
   .KATI_READONLY := BOARD_API_LEVEL
diff --git a/core/product_config.mk b/core/product_config.mk
index fae2c1a..d16c38d 100644
--- a/core/product_config.mk
+++ b/core/product_config.mk
@@ -569,20 +569,27 @@
       $(PRODUCT_ENFORCE_RRO_EXEMPTED_TARGETS))
 endif
 
-# Get the board API level.
-board_api_level := $(PLATFORM_SDK_VERSION)
-ifdef BOARD_API_LEVEL
-  board_api_level := $(BOARD_API_LEVEL)
-else ifdef BOARD_SHIPPING_API_LEVEL
-  # Vendors with GRF must define BOARD_SHIPPING_API_LEVEL for the vendor API level.
-  board_api_level := $(BOARD_SHIPPING_API_LEVEL)
-endif
+# This table maps sdk version 35 to vendor api level 202404 and assumes yearly
+# release for the same month.
+define sdk-to-vendor-api-level
+  $(if $(call math_lt_or_eq,$(1),34),$(1),20$(call int_subtract,$(1),11)04)
+endef
 
-# Calculate the VSR vendor API level.
-VSR_VENDOR_API_LEVEL := $(board_api_level)
-
-ifdef PRODUCT_SHIPPING_API_LEVEL
-  VSR_VENDOR_API_LEVEL := $(call math_min,$(PRODUCT_SHIPPING_API_LEVEL),$(board_api_level))
+ifdef PRODUCT_SHIPPING_VENDOR_API_LEVEL
+# Follow the version that is set manually.
+  VSR_VENDOR_API_LEVEL := $(PRODUCT_SHIPPING_VENDOR_API_LEVEL)
+else
+  # VSR API level is the vendor api level of the product shipping API level.
+  VSR_VENDOR_API_LEVEL := $(call sdk-to-vendor-api-level,$(PLATFORM_SDK_VERSION))
+  ifdef PRODUCT_SHIPPING_API_LEVEL
+    VSR_VENDOR_API_LEVEL := $(call sdk-to-vendor-api-level,$(PRODUCT_SHIPPING_API_LEVEL))
+  endif
+  ifdef BOARD_SHIPPING_API_LEVEL
+    # Vendors with GRF must define BOARD_SHIPPING_API_LEVEL for the vendor API level.
+    # In this case, the VSR API level is the minimum of the PRODUCT_SHIPPING_API_LEVEL
+    # and RELEASE_BOARD_API_LEVEL
+    VSR_VENDOR_API_LEVEL := $(call math_min,$(VSR_VENDOR_API_LEVEL),$(RELEASE_BOARD_API_LEVEL))
+  endif
 endif
 .KATI_READONLY := VSR_VENDOR_API_LEVEL
 
@@ -597,7 +604,7 @@
 
 # Boolean variable determining if selinux labels of /dev are enforced
 CHECK_DEV_TYPE_VIOLATIONS := false
-ifneq ($(call math_gt,$(VSR_VENDOR_API_LEVEL),35),)
+ifneq ($(call math_gt,$(VSR_VENDOR_API_LEVEL),202404),)
   CHECK_DEV_TYPE_VIOLATIONS := true
 else ifneq ($(PRODUCT_CHECK_DEV_TYPE_VIOLATIONS),)
   CHECK_DEV_TYPE_VIOLATIONS := $(PRODUCT_CHECK_DEV_TYPE_VIOLATIONS)
@@ -623,15 +630,6 @@
 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/release_config.mk b/core/release_config.mk
index a7b5b3f..3e51af5 100644
--- a/core/release_config.mk
+++ b/core/release_config.mk
@@ -41,8 +41,7 @@
 # which has OWNERS control.  If it isn't let others define their own.
 # TODO: Remove wildcard for build/release one when all branch manifests
 # have updated.
-config_map_files := $(wildcard build/trunk_release/release_config_map.mk) \
-    $(wildcard build/release/release_config_map.mk) \
+config_map_files := $(wildcard build/release/release_config_map.mk) \
     $(wildcard vendor/google_shared/build/release/release_config_map.mk) \
     $(if $(wildcard vendor/google/release/release_config_map.mk), \
         vendor/google/release/release_config_map.mk, \
diff --git a/core/tasks/berberis_test.mk b/core/tasks/berberis_test.mk
new file mode 100644
index 0000000..8604709
--- /dev/null
+++ b/core/tasks/berberis_test.mk
@@ -0,0 +1,25 @@
+#
+# Copyright (C) 2023 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.
+#
+
+BERBERIS_DIR := frameworks/libs/binary_translation
+
+# Berberis includes some components which may conflict with other packages.
+# Only build it when requested explicitly.
+ifeq ($(BUILD_BERBERIS),true)
+
+include $(BERBERIS_DIR)/tests/run_host_tests.mk
+
+endif  # BUILD_BERBERIS
diff --git a/core/tasks/meta-lic.mk b/core/tasks/meta-lic.mk
index dea4892..0348844 100644
--- a/core/tasks/meta-lic.mk
+++ b/core/tasks/meta-lic.mk
@@ -14,6 +14,9 @@
 
 # Declare license metadata for non-module files released with products.
 
+# Moved here from device/sample/Android.mk
+$(eval $(call declare-1p-copy-files,device/sample,))
+
 # Moved here from frameworks/av/media/Android.mk
 $(eval $(call declare-1p-copy-files,frameworks/av/media/libeffects,audio_effects.conf))
 $(eval $(call declare-1p-copy-files,frameworks/av/media/libeffects,audio_effects.xml))
diff --git a/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/sdk.mk b/target/product/sdk.mk
index 04649a2..1a07363 100644
--- a/target/product/sdk.mk
+++ b/target/product/sdk.mk
@@ -34,6 +34,9 @@
 
 PRODUCT_BUILD_FROM_SOURCE_STUB := true
 
+# Use sources of mainline modules
+PRODUCT_MODULE_BUILD_FROM_SOURCE := true
+
 ifeq ($(WITHOUT_CHECK_API),true)
   $(error WITHOUT_CHECK_API cannot be set to true for SDK product builds)
 endif
diff --git a/target/product/virtual_ab_ota/android_t_baseline.mk b/target/product/virtual_ab_ota/android_t_baseline.mk
index 418aaa4..af0f7a9 100644
--- a/target/product/virtual_ab_ota/android_t_baseline.mk
+++ b/target/product/virtual_ab_ota/android_t_baseline.mk
@@ -20,3 +20,5 @@
 #
 # 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/TEST_MAPPING b/tools/aconfig/TEST_MAPPING
index 7651dba..638b92a 100644
--- a/tools/aconfig/TEST_MAPPING
+++ b/tools/aconfig/TEST_MAPPING
@@ -39,6 +39,10 @@
     //   "name": "aconfig.exported_mode.test.rust"
     // },
     {
+      // aflags CLI unit tests
+      "name": "aflags.test"
+    },
+    {
       // printflags unit tests
       "name": "printflags.test"
     },
@@ -66,9 +70,7 @@
       // test testing filtering logic. Breakage on this test means all tests
       // that using the flag macros to do filtering will get affected.
       "name": "FlagMacrosTests"
-    }
-  ],
-  "postsubmit": [
+    },
     {
       // aconfig_storage_write_api unit tests
       "name": "aconfig_storage_write_api.test"
@@ -82,21 +84,18 @@
       "name": "aconfig_storage_write_api.test.rust"
     },
     {
-      // aconfig_storage write api cpp integration tests
-      "name": "aconfig_storage_write_api.test.cpp"
-    },
-    {
       // aconfig_storage read api rust integration tests
       "name": "aconfig_storage_read_api.test.rust"
     },
     {
       // aconfig_storage read api cpp integration tests
       "name": "aconfig_storage_read_api.test.cpp"
-    },
+    }
+  ],
+  "postsubmit": [
     {
-      // aflags CLI unit tests
-      // TODO(b/326062088): add to presubmit once proven in postsubmit.
-      "name": "aflags.test"
+      // aconfig_storage write api cpp integration tests
+      "name": "aconfig_storage_write_api.test.cpp"
     }
   ]
 }
diff --git a/tools/aconfig/aconfig/src/codegen/java.rs b/tools/aconfig/aconfig/src/codegen/java.rs
index fab2fa3..920d5fa 100644
--- a/tools/aconfig/aconfig/src/codegen/java.rs
+++ b/tools/aconfig/aconfig/src/codegen/java.rs
@@ -180,27 +180,36 @@
     import android.compat.annotation.UnsupportedAppUsage;
     /** @hide */
     public interface FeatureFlags {
+        @com.android.aconfig.annotations.AconfigFlagAccessor
         @com.android.aconfig.annotations.AssumeFalseForR8
         @UnsupportedAppUsage
         boolean disabledRo();
+        @com.android.aconfig.annotations.AconfigFlagAccessor
         @UnsupportedAppUsage
         boolean disabledRw();
+        @com.android.aconfig.annotations.AconfigFlagAccessor
         @UnsupportedAppUsage
         boolean disabledRwExported();
+        @com.android.aconfig.annotations.AconfigFlagAccessor
         @UnsupportedAppUsage
         boolean disabledRwInOtherNamespace();
+        @com.android.aconfig.annotations.AconfigFlagAccessor
         @com.android.aconfig.annotations.AssumeTrueForR8
         @UnsupportedAppUsage
         boolean enabledFixedRo();
+        @com.android.aconfig.annotations.AconfigFlagAccessor
         @com.android.aconfig.annotations.AssumeTrueForR8
         @UnsupportedAppUsage
         boolean enabledFixedRoExported();
+        @com.android.aconfig.annotations.AconfigFlagAccessor
         @com.android.aconfig.annotations.AssumeTrueForR8
         @UnsupportedAppUsage
         boolean enabledRo();
+        @com.android.aconfig.annotations.AconfigFlagAccessor
         @com.android.aconfig.annotations.AssumeTrueForR8
         @UnsupportedAppUsage
         boolean enabledRoExported();
+        @com.android.aconfig.annotations.AconfigFlagAccessor
         @UnsupportedAppUsage
         boolean enabledRw();
     }
@@ -231,43 +240,52 @@
         /** @hide */
         public static final String FLAG_ENABLED_RW = "com.android.aconfig.test.enabled_rw";
 
+        @com.android.aconfig.annotations.AconfigFlagAccessor
         @com.android.aconfig.annotations.AssumeFalseForR8
         @UnsupportedAppUsage
         public static boolean disabledRo() {
             return FEATURE_FLAGS.disabledRo();
         }
+        @com.android.aconfig.annotations.AconfigFlagAccessor
         @UnsupportedAppUsage
         public static boolean disabledRw() {
             return FEATURE_FLAGS.disabledRw();
         }
+        @com.android.aconfig.annotations.AconfigFlagAccessor
         @UnsupportedAppUsage
         public static boolean disabledRwExported() {
             return FEATURE_FLAGS.disabledRwExported();
         }
+        @com.android.aconfig.annotations.AconfigFlagAccessor
         @UnsupportedAppUsage
         public static boolean disabledRwInOtherNamespace() {
             return FEATURE_FLAGS.disabledRwInOtherNamespace();
         }
+        @com.android.aconfig.annotations.AconfigFlagAccessor
         @com.android.aconfig.annotations.AssumeTrueForR8
         @UnsupportedAppUsage
         public static boolean enabledFixedRo() {
             return FEATURE_FLAGS.enabledFixedRo();
         }
+        @com.android.aconfig.annotations.AconfigFlagAccessor
         @com.android.aconfig.annotations.AssumeTrueForR8
         @UnsupportedAppUsage
         public static boolean enabledFixedRoExported() {
             return FEATURE_FLAGS.enabledFixedRoExported();
         }
+        @com.android.aconfig.annotations.AconfigFlagAccessor
         @com.android.aconfig.annotations.AssumeTrueForR8
         @UnsupportedAppUsage
         public static boolean enabledRo() {
             return FEATURE_FLAGS.enabledRo();
         }
+        @com.android.aconfig.annotations.AconfigFlagAccessor
         @com.android.aconfig.annotations.AssumeTrueForR8
         @UnsupportedAppUsage
         public static boolean enabledRoExported() {
             return FEATURE_FLAGS.enabledRoExported();
         }
+        @com.android.aconfig.annotations.AconfigFlagAccessor
         @UnsupportedAppUsage
         public static boolean enabledRw() {
             return FEATURE_FLAGS.enabledRw();
@@ -458,12 +476,13 @@
                 other_namespace_is_cached = true;
             }
 
-
+            @com.android.aconfig.annotations.AconfigFlagAccessor
             @Override
             @UnsupportedAppUsage
             public boolean disabledRo() {
                 return false;
             }
+            @com.android.aconfig.annotations.AconfigFlagAccessor
             @Override
             @UnsupportedAppUsage
             public boolean disabledRw() {
@@ -472,6 +491,7 @@
                 }
                 return disabledRw;
             }
+            @com.android.aconfig.annotations.AconfigFlagAccessor
             @Override
             @UnsupportedAppUsage
             public boolean disabledRwExported() {
@@ -480,6 +500,7 @@
                 }
                 return disabledRwExported;
             }
+            @com.android.aconfig.annotations.AconfigFlagAccessor
             @Override
             @UnsupportedAppUsage
             public boolean disabledRwInOtherNamespace() {
@@ -488,26 +509,31 @@
                 }
                 return disabledRwInOtherNamespace;
             }
+            @com.android.aconfig.annotations.AconfigFlagAccessor
             @Override
             @UnsupportedAppUsage
             public boolean enabledFixedRo() {
                 return true;
             }
+            @com.android.aconfig.annotations.AconfigFlagAccessor
             @Override
             @UnsupportedAppUsage
             public boolean enabledFixedRoExported() {
                 return true;
             }
+            @com.android.aconfig.annotations.AconfigFlagAccessor
             @Override
             @UnsupportedAppUsage
             public boolean enabledRo() {
                 return true;
             }
+            @com.android.aconfig.annotations.AconfigFlagAccessor
             @Override
             @UnsupportedAppUsage
             public boolean enabledRoExported() {
                 return true;
             }
+            @com.android.aconfig.annotations.AconfigFlagAccessor
             @Override
             @UnsupportedAppUsage
             public boolean enabledRw() {
@@ -566,13 +592,15 @@
             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();
             }
@@ -584,8 +612,11 @@
         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();
         }
         "#;
@@ -623,7 +654,7 @@
                 }
                 aconfig_test_is_cached = true;
             }
-
+            @com.android.aconfig.annotations.AconfigFlagAccessor
             @Override
             public boolean disabledRwExported() {
                 if (!aconfig_test_is_cached) {
@@ -631,7 +662,7 @@
                 }
                 return disabledRwExported;
             }
-
+            @com.android.aconfig.annotations.AconfigFlagAccessor
             @Override
             public boolean enabledFixedRoExported() {
                 if (!aconfig_test_is_cached) {
@@ -639,7 +670,7 @@
                 }
                 return enabledFixedRoExported;
             }
-
+            @com.android.aconfig.annotations.AconfigFlagAccessor
             @Override
             public boolean enabledRoExported() {
                 if (!aconfig_test_is_cached) {
@@ -761,54 +792,63 @@
         import android.compat.annotation.UnsupportedAppUsage;
         /** @hide */
         public final class FeatureFlagsImpl implements FeatureFlags {
+            @com.android.aconfig.annotations.AconfigFlagAccessor
             @Override
             @UnsupportedAppUsage
             public boolean disabledRo() {
                 throw new UnsupportedOperationException(
                     "Method is not implemented.");
             }
+            @com.android.aconfig.annotations.AconfigFlagAccessor
             @Override
             @UnsupportedAppUsage
             public boolean disabledRw() {
                 throw new UnsupportedOperationException(
                     "Method is not implemented.");
             }
+            @com.android.aconfig.annotations.AconfigFlagAccessor
             @Override
             @UnsupportedAppUsage
             public boolean disabledRwExported() {
                 throw new UnsupportedOperationException(
                     "Method is not implemented.");
             }
+            @com.android.aconfig.annotations.AconfigFlagAccessor
             @Override
             @UnsupportedAppUsage
             public boolean disabledRwInOtherNamespace() {
                 throw new UnsupportedOperationException(
                     "Method is not implemented.");
             }
+            @com.android.aconfig.annotations.AconfigFlagAccessor
             @Override
             @UnsupportedAppUsage
             public boolean enabledFixedRo() {
                 throw new UnsupportedOperationException(
                     "Method is not implemented.");
             }
+            @com.android.aconfig.annotations.AconfigFlagAccessor
             @Override
             @UnsupportedAppUsage
             public boolean enabledFixedRoExported() {
                 throw new UnsupportedOperationException(
                     "Method is not implemented.");
             }
+            @com.android.aconfig.annotations.AconfigFlagAccessor
             @Override
             @UnsupportedAppUsage
             public boolean enabledRo() {
                 throw new UnsupportedOperationException(
                     "Method is not implemented.");
             }
+            @com.android.aconfig.annotations.AconfigFlagAccessor
             @Override
             @UnsupportedAppUsage
             public boolean enabledRoExported() {
                 throw new UnsupportedOperationException(
                     "Method is not implemented.");
             }
+            @com.android.aconfig.annotations.AconfigFlagAccessor
             @Override
             @UnsupportedAppUsage
             public boolean enabledRw() {
@@ -861,21 +901,27 @@
         import android.compat.annotation.UnsupportedAppUsage;
         /** @hide */
         public interface FeatureFlags {
+            @com.android.aconfig.annotations.AconfigFlagAccessor
             @com.android.aconfig.annotations.AssumeFalseForR8
             @UnsupportedAppUsage
             boolean disabledRo();
+            @com.android.aconfig.annotations.AconfigFlagAccessor
             @com.android.aconfig.annotations.AssumeFalseForR8
             @UnsupportedAppUsage
             boolean disabledRw();
+            @com.android.aconfig.annotations.AconfigFlagAccessor
             @com.android.aconfig.annotations.AssumeFalseForR8
             @UnsupportedAppUsage
             boolean disabledRwInOtherNamespace();
+            @com.android.aconfig.annotations.AconfigFlagAccessor
             @com.android.aconfig.annotations.AssumeTrueForR8
             @UnsupportedAppUsage
             boolean enabledFixedRo();
+            @com.android.aconfig.annotations.AconfigFlagAccessor
             @com.android.aconfig.annotations.AssumeTrueForR8
             @UnsupportedAppUsage
             boolean enabledRo();
+            @com.android.aconfig.annotations.AconfigFlagAccessor
             @com.android.aconfig.annotations.AssumeTrueForR8
             @UnsupportedAppUsage
             boolean enabledRw();
@@ -887,31 +933,37 @@
         import android.compat.annotation.UnsupportedAppUsage;
         /** @hide */
         public final class FeatureFlagsImpl implements FeatureFlags {
+            @com.android.aconfig.annotations.AconfigFlagAccessor
             @Override
             @UnsupportedAppUsage
             public boolean disabledRo() {
                 return false;
             }
+            @com.android.aconfig.annotations.AconfigFlagAccessor
             @Override
             @UnsupportedAppUsage
             public boolean disabledRw() {
                 return false;
             }
+            @com.android.aconfig.annotations.AconfigFlagAccessor
             @Override
             @UnsupportedAppUsage
             public boolean disabledRwInOtherNamespace() {
                 return false;
             }
+            @com.android.aconfig.annotations.AconfigFlagAccessor
             @Override
             @UnsupportedAppUsage
             public boolean enabledFixedRo() {
                 return true;
             }
+            @com.android.aconfig.annotations.AconfigFlagAccessor
             @Override
             @UnsupportedAppUsage
             public boolean enabledRo() {
                 return true;
             }
+            @com.android.aconfig.annotations.AconfigFlagAccessor
             @Override
             @UnsupportedAppUsage
             public boolean enabledRw() {
@@ -938,32 +990,37 @@
             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
             @UnsupportedAppUsage
             public static boolean disabledRo() {
                 return FEATURE_FLAGS.disabledRo();
             }
+            @com.android.aconfig.annotations.AconfigFlagAccessor
             @com.android.aconfig.annotations.AssumeFalseForR8
             @UnsupportedAppUsage
             public static boolean disabledRw() {
                 return FEATURE_FLAGS.disabledRw();
             }
+            @com.android.aconfig.annotations.AconfigFlagAccessor
             @com.android.aconfig.annotations.AssumeFalseForR8
             @UnsupportedAppUsage
             public static boolean disabledRwInOtherNamespace() {
                 return FEATURE_FLAGS.disabledRwInOtherNamespace();
             }
+            @com.android.aconfig.annotations.AconfigFlagAccessor
             @com.android.aconfig.annotations.AssumeTrueForR8
             @UnsupportedAppUsage
             public static boolean enabledFixedRo() {
                 return FEATURE_FLAGS.enabledFixedRo();
             }
+            @com.android.aconfig.annotations.AconfigFlagAccessor
             @com.android.aconfig.annotations.AssumeTrueForR8
             @UnsupportedAppUsage
             public static boolean enabledRo() {
                 return FEATURE_FLAGS.enabledRo();
             }
+            @com.android.aconfig.annotations.AconfigFlagAccessor
             @com.android.aconfig.annotations.AssumeTrueForR8
             @UnsupportedAppUsage
             public static boolean enabledRw() {
diff --git a/tools/aconfig/aconfig/src/storage/flag_table.rs b/tools/aconfig/aconfig/src/storage/flag_table.rs
index d4f4bc2..b339821 100644
--- a/tools/aconfig/aconfig/src/storage/flag_table.rs
+++ b/tools/aconfig/aconfig/src/storage/flag_table.rs
@@ -16,8 +16,10 @@
 
 use crate::commands::assign_flag_ids;
 use crate::storage::FlagPackage;
+use aconfig_protos::ProtoFlagPermission;
 use aconfig_storage_file::{
-    get_table_size, FlagTable, FlagTableHeader, FlagTableNode, StorageFileType, FILE_VERSION,
+    get_table_size, FlagTable, FlagTableHeader, FlagTableNode, StorageFileType, StoredFlagType,
+    FILE_VERSION,
 };
 use anyhow::{anyhow, Result};
 
@@ -45,7 +47,7 @@
     fn new(
         package_id: u32,
         flag_name: &str,
-        flag_type: u16,
+        flag_type: StoredFlagType,
         flag_id: u16,
         num_buckets: u32,
     ) -> Self {
@@ -70,11 +72,14 @@
                 let fid = flag_ids
                     .get(pf.name())
                     .ok_or(anyhow!(format!("missing flag id for {}", pf.name())))?;
-                // all flags are boolean value at the moment, thus using the last bit.
-                // When more flag value types are supported, flag value type information
-                // should come from the parsed flag, and we will set the flag_type bit
-                // mask properly.
-                let flag_type = 1;
+                let flag_type = if pf.is_fixed_read_only() {
+                    StoredFlagType::FixedReadOnlyBoolean
+                } else {
+                    match pf.permission() {
+                        ProtoFlagPermission::READ_WRITE => StoredFlagType::ReadWriteBoolean,
+                        ProtoFlagPermission::READ_ONLY => StoredFlagType::ReadOnlyBoolean,
+                    }
+                };
                 Ok(Self::new(package.package_id, pf.name(), flag_type, *fid, num_buckets))
             })
             .collect::<Result<Vec<_>>>()
@@ -95,10 +100,10 @@
         .concat();
 
     // initialize all header fields
-    header.bucket_offset = header.as_bytes().len() as u32;
+    header.bucket_offset = header.into_bytes().len() as u32;
     header.node_offset = header.bucket_offset + num_buckets * 4;
     header.file_size = header.node_offset
-        + node_wrappers.iter().map(|x| x.node.as_bytes().len()).sum::<usize>() as u32;
+        + node_wrappers.iter().map(|x| x.node.into_bytes().len()).sum::<usize>() as u32;
 
     // sort nodes by bucket index for efficiency
     node_wrappers.sort_by(|a, b| a.bucket_index.cmp(&b.bucket_index));
@@ -116,7 +121,7 @@
         if buckets[node_bucket_idx as usize].is_none() {
             buckets[node_bucket_idx as usize] = Some(offset);
         }
-        offset += node_wrappers[i].node.as_bytes().len() as u32;
+        offset += node_wrappers[i].node.into_bytes().len() as u32;
 
         if let Some(index) = next_node_bucket_idx {
             if index == node_bucket_idx {
@@ -136,79 +141,18 @@
     use super::*;
     use crate::storage::{group_flags_by_package, tests::parse_all_test_flags};
 
-    // create test baseline, syntactic sugar
-    fn new_expected_node(
-        package_id: u32,
-        flag_name: &str,
-        flag_type: u16,
-        flag_id: u16,
-        next_offset: Option<u32>,
-    ) -> FlagTableNode {
-        FlagTableNode {
-            package_id,
-            flag_name: flag_name.to_string(),
-            flag_type,
-            flag_id,
-            next_offset,
-        }
-    }
-
-    fn create_test_flag_table() -> Result<FlagTable> {
+    fn create_test_flag_table_from_source() -> Result<FlagTable> {
         let caches = parse_all_test_flags();
         let packages = group_flags_by_package(caches.iter());
-        create_flag_table("system", &packages)
+        create_flag_table("mockup", &packages)
     }
 
     #[test]
     // this test point locks down the table creation and each field
     fn test_table_contents() {
-        let flag_table = create_test_flag_table();
+        let flag_table = create_test_flag_table_from_source();
         assert!(flag_table.is_ok());
-
-        let header: &FlagTableHeader = &flag_table.as_ref().unwrap().header;
-        let expected_header = FlagTableHeader {
-            version: FILE_VERSION,
-            container: String::from("system"),
-            file_type: StorageFileType::FlagMap as u8,
-            file_size: 321,
-            num_flags: 8,
-            bucket_offset: 31,
-            node_offset: 99,
-        };
-        assert_eq!(header, &expected_header);
-
-        let buckets: &Vec<Option<u32>> = &flag_table.as_ref().unwrap().buckets;
-        let expected_bucket: Vec<Option<u32>> = vec![
-            Some(99),
-            Some(125),
-            None,
-            None,
-            None,
-            Some(178),
-            None,
-            Some(204),
-            None,
-            Some(262),
-            None,
-            None,
-            None,
-            None,
-            None,
-            Some(294),
-            None,
-        ];
-        assert_eq!(buckets, &expected_bucket);
-
-        let nodes: &Vec<FlagTableNode> = &flag_table.as_ref().unwrap().nodes;
-        assert_eq!(nodes.len(), 8);
-
-        assert_eq!(nodes[0], new_expected_node(0, "enabled_ro", 1, 1, None));
-        assert_eq!(nodes[1], new_expected_node(0, "enabled_rw", 1, 2, Some(151)));
-        assert_eq!(nodes[2], new_expected_node(1, "disabled_ro", 1, 0, None));
-        assert_eq!(nodes[3], new_expected_node(2, "enabled_ro", 1, 1, None));
-        assert_eq!(nodes[4], new_expected_node(1, "enabled_fixed_ro", 1, 1, Some(236)));
-        assert_eq!(nodes[5], new_expected_node(1, "enabled_ro", 1, 2, None));
-        assert_eq!(nodes[6], new_expected_node(2, "enabled_fixed_ro", 1, 0, None));
-        assert_eq!(nodes[7], new_expected_node(0, "disabled_rw", 1, 0, None));
+        let expected_flag_table = aconfig_storage_file::test_utils::create_test_flag_table();
+        assert_eq!(flag_table.unwrap(), expected_flag_table);
     }
 }
diff --git a/tools/aconfig/aconfig/src/storage/flag_value.rs b/tools/aconfig/aconfig/src/storage/flag_value.rs
index 293615e..a37ad9f 100644
--- a/tools/aconfig/aconfig/src/storage/flag_value.rs
+++ b/tools/aconfig/aconfig/src/storage/flag_value.rs
@@ -53,7 +53,7 @@
     }
 
     // initialize all header fields
-    list.header.boolean_value_offset = list.header.as_bytes().len() as u32;
+    list.header.boolean_value_offset = list.header.into_bytes().len() as u32;
     list.header.file_size = list.header.boolean_value_offset + num_flags;
 
     Ok(list)
@@ -64,31 +64,19 @@
     use super::*;
     use crate::storage::{group_flags_by_package, tests::parse_all_test_flags};
 
-    pub fn create_test_flag_value_list() -> Result<FlagValueList> {
+    pub fn create_test_flag_value_list_from_source() -> Result<FlagValueList> {
         let caches = parse_all_test_flags();
         let packages = group_flags_by_package(caches.iter());
-        create_flag_value("system", &packages)
+        create_flag_value("mockup", &packages)
     }
 
     #[test]
     // this test point locks down the flag value creation and each field
     fn test_list_contents() {
-        let flag_value_list = create_test_flag_value_list();
+        let flag_value_list = create_test_flag_value_list_from_source();
         assert!(flag_value_list.is_ok());
-
-        let header: &FlagValueHeader = &flag_value_list.as_ref().unwrap().header;
-        let expected_header = FlagValueHeader {
-            version: FILE_VERSION,
-            container: String::from("system"),
-            file_type: StorageFileType::FlagVal as u8,
-            file_size: 35,
-            num_flags: 8,
-            boolean_value_offset: 27,
-        };
-        assert_eq!(header, &expected_header);
-
-        let booleans: &Vec<bool> = &flag_value_list.as_ref().unwrap().booleans;
-        let expected_booleans: Vec<bool> = vec![false; header.num_flags as usize];
-        assert_eq!(booleans, &expected_booleans);
+        let expected_flag_value_list =
+            aconfig_storage_file::test_utils::create_test_flag_value_list();
+        assert_eq!(flag_value_list.unwrap(), expected_flag_value_list);
     }
 }
diff --git a/tools/aconfig/aconfig/src/storage/mod.rs b/tools/aconfig/aconfig/src/storage/mod.rs
index 3f5f8de..30517de 100644
--- a/tools/aconfig/aconfig/src/storage/mod.rs
+++ b/tools/aconfig/aconfig/src/storage/mod.rs
@@ -97,15 +97,15 @@
     match file {
         StorageFileType::PackageMap => {
             let package_table = create_package_table(container, &packages)?;
-            Ok(package_table.as_bytes())
+            Ok(package_table.into_bytes())
         }
         StorageFileType::FlagMap => {
             let flag_table = create_flag_table(container, &packages)?;
-            Ok(flag_table.as_bytes())
+            Ok(flag_table.into_bytes())
         }
         StorageFileType::FlagVal => {
             let flag_value = create_flag_value(container, &packages)?;
-            Ok(flag_value.as_bytes())
+            Ok(flag_value.into_bytes())
         }
         _ => Err(anyhow!("aconfig does not support the creation of this storage file type")),
     }
@@ -122,30 +122,38 @@
                 "com.android.aconfig.storage.test_1",
                 "storage_test_1.aconfig",
                 include_bytes!("../../tests/storage_test_1.aconfig").as_slice(),
+                "storage_test_1.value",
+                include_bytes!("../../tests/storage_test_1.values").as_slice(),
             ),
             (
                 "com.android.aconfig.storage.test_2",
                 "storage_test_2.aconfig",
                 include_bytes!("../../tests/storage_test_2.aconfig").as_slice(),
+                "storage_test_2.value",
+                include_bytes!("../../tests/storage_test_2.values").as_slice(),
             ),
             (
                 "com.android.aconfig.storage.test_4",
                 "storage_test_4.aconfig",
                 include_bytes!("../../tests/storage_test_4.aconfig").as_slice(),
+                "storage_test_4.value",
+                include_bytes!("../../tests/storage_test_4.values").as_slice(),
             ),
         ];
-
         aconfig_files
             .into_iter()
-            .map(|(pkg, file, content)| {
+            .map(|(pkg, aconfig_file, aconfig_content, value_file, value_content)| {
                 let bytes = crate::commands::parse_flags(
                     pkg,
                     Some("system"),
                     vec![Input {
-                        source: format!("tests/{}", file).to_string(),
-                        reader: Box::new(content),
+                        source: format!("tests/{}", aconfig_file).to_string(),
+                        reader: Box::new(aconfig_content),
                     }],
-                    vec![],
+                    vec![Input {
+                        source: format!("tests/{}", value_file).to_string(),
+                        reader: Box::new(value_content),
+                    }],
                     crate::commands::DEFAULT_FLAG_PERMISSION,
                 )
                 .unwrap();
diff --git a/tools/aconfig/aconfig/src/storage/package_table.rs b/tools/aconfig/aconfig/src/storage/package_table.rs
index ca0dec3..0a3df77 100644
--- a/tools/aconfig/aconfig/src/storage/package_table.rs
+++ b/tools/aconfig/aconfig/src/storage/package_table.rs
@@ -66,10 +66,10 @@
         packages.iter().map(|pkg| PackageTableNodeWrapper::new(pkg, num_buckets)).collect();
 
     // initialize all header fields
-    header.bucket_offset = header.as_bytes().len() as u32;
+    header.bucket_offset = header.into_bytes().len() as u32;
     header.node_offset = header.bucket_offset + num_buckets * 4;
     header.file_size = header.node_offset
-        + node_wrappers.iter().map(|x| x.node.as_bytes().len()).sum::<usize>() as u32;
+        + node_wrappers.iter().map(|x| x.node.into_bytes().len()).sum::<usize>() as u32;
 
     // sort node_wrappers by bucket index for efficiency
     node_wrappers.sort_by(|a, b| a.bucket_index.cmp(&b.bucket_index));
@@ -87,7 +87,7 @@
         if buckets[node_bucket_idx as usize].is_none() {
             buckets[node_bucket_idx as usize] = Some(offset);
         }
-        offset += node_wrappers[i].node.as_bytes().len() as u32;
+        offset += node_wrappers[i].node.into_bytes().len() as u32;
 
         if let Some(index) = next_node_bucket_idx {
             if index == node_bucket_idx {
@@ -109,56 +109,18 @@
     use super::*;
     use crate::storage::{group_flags_by_package, tests::parse_all_test_flags};
 
-    pub fn create_test_package_table() -> Result<PackageTable> {
+    pub fn create_test_package_table_from_source() -> Result<PackageTable> {
         let caches = parse_all_test_flags();
         let packages = group_flags_by_package(caches.iter());
-        create_package_table("system", &packages)
+        create_package_table("mockup", &packages)
     }
 
     #[test]
     // this test point locks down the table creation and each field
     fn test_table_contents() {
-        let package_table = create_test_package_table();
+        let package_table = create_test_package_table_from_source();
         assert!(package_table.is_ok());
-
-        let header: &PackageTableHeader = &package_table.as_ref().unwrap().header;
-        let expected_header = PackageTableHeader {
-            version: FILE_VERSION,
-            container: String::from("system"),
-            file_type: StorageFileType::PackageMap as u8,
-            file_size: 209,
-            num_packages: 3,
-            bucket_offset: 31,
-            node_offset: 59,
-        };
-        assert_eq!(header, &expected_header);
-
-        let buckets: &Vec<Option<u32>> = &package_table.as_ref().unwrap().buckets;
-        let expected: Vec<Option<u32>> = vec![Some(59), None, None, Some(109), None, None, None];
-        assert_eq!(buckets, &expected);
-
-        let nodes: &Vec<PackageTableNode> = &package_table.as_ref().unwrap().nodes;
-        assert_eq!(nodes.len(), 3);
-        let first_node_expected = PackageTableNode {
-            package_name: String::from("com.android.aconfig.storage.test_2"),
-            package_id: 1,
-            boolean_offset: 3,
-            next_offset: None,
-        };
-        assert_eq!(nodes[0], first_node_expected);
-        let second_node_expected = PackageTableNode {
-            package_name: String::from("com.android.aconfig.storage.test_1"),
-            package_id: 0,
-            boolean_offset: 0,
-            next_offset: Some(159),
-        };
-        assert_eq!(nodes[1], second_node_expected);
-        let third_node_expected = PackageTableNode {
-            package_name: String::from("com.android.aconfig.storage.test_4"),
-            package_id: 2,
-            boolean_offset: 6,
-            next_offset: None,
-        };
-        assert_eq!(nodes[2], third_node_expected);
+        let expected_package_table = aconfig_storage_file::test_utils::create_test_package_table();
+        assert_eq!(package_table.unwrap(), expected_package_table);
     }
 }
diff --git a/tools/aconfig/aconfig/templates/FeatureFlags.java.template b/tools/aconfig/aconfig/templates/FeatureFlags.java.template
index 13edcb4..b90b201 100644
--- a/tools/aconfig/aconfig/templates/FeatureFlags.java.template
+++ b/tools/aconfig/aconfig/templates/FeatureFlags.java.template
@@ -6,6 +6,7 @@
 /** @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
diff --git a/tools/aconfig/aconfig/templates/FeatureFlagsImpl.java.template b/tools/aconfig/aconfig/templates/FeatureFlagsImpl.java.template
index 12b2fc1..704f25b 100644
--- a/tools/aconfig/aconfig/templates/FeatureFlagsImpl.java.template
+++ b/tools/aconfig/aconfig/templates/FeatureFlagsImpl.java.template
@@ -45,6 +45,7 @@
 {{ endfor- }}
 {{ -endif }}{#- end of runtime_lookup_required #}
 {{ -for flag in flag_elements }}
+    @com.android.aconfig.annotations.AconfigFlagAccessor
     @Override
 {{ -if not library_exported }}
     @UnsupportedAppUsage
@@ -66,6 +67,7 @@
 /** @hide */
 public final class FeatureFlagsImpl implements FeatureFlags \{
 {{ for flag in flag_elements }}
+    @com.android.aconfig.annotations.AconfigFlagAccessor
     @Override
 {{ -if not library_exported }}
     @UnsupportedAppUsage
diff --git a/tools/aconfig/aconfig/templates/Flags.java.template b/tools/aconfig/aconfig/templates/Flags.java.template
index e105991..55db924 100644
--- a/tools/aconfig/aconfig/templates/Flags.java.template
+++ b/tools/aconfig/aconfig/templates/Flags.java.template
@@ -10,6 +10,7 @@
     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
diff --git a/tools/aconfig/aconfig/tests/storage_test_1.values b/tools/aconfig/aconfig/tests/storage_test_1.values
new file mode 100644
index 0000000..35548ae
--- /dev/null
+++ b/tools/aconfig/aconfig/tests/storage_test_1.values
@@ -0,0 +1,18 @@
+flag_value {
+    package: "com.android.aconfig.storage.test_1"
+    name: "enabled_rw"
+    state: ENABLED
+    permission: READ_WRITE
+}
+flag_value {
+    package: "com.android.aconfig.storage.test_1"
+    name: "disabled_rw"
+    state: DISABLED
+    permission: READ_WRITE
+}
+flag_value {
+    package: "com.android.aconfig.storage.test_1"
+    name: "enabled_ro"
+    state: ENABLED
+    permission: READ_ONLY
+}
diff --git a/tools/aconfig/aconfig/tests/storage_test_2.values b/tools/aconfig/aconfig/tests/storage_test_2.values
new file mode 100644
index 0000000..a7bb0b1
--- /dev/null
+++ b/tools/aconfig/aconfig/tests/storage_test_2.values
@@ -0,0 +1,18 @@
+flag_value {
+    package: "com.android.aconfig.storage.test_2"
+    name: "enabled_ro"
+    state: ENABLED
+    permission: READ_ONLY
+}
+flag_value {
+    package: "com.android.aconfig.storage.test_2"
+    name: "disabled_ro"
+    state: DISABLED
+    permission: READ_ONLY
+}
+flag_value {
+    package: "com.android.aconfig.storage.test_2"
+    name: "enabled_fixed_ro"
+    state: ENABLED
+    permission: READ_ONLY
+}
diff --git a/tools/aconfig/aconfig/tests/storage_test_4.values b/tools/aconfig/aconfig/tests/storage_test_4.values
new file mode 100644
index 0000000..fa21317
--- /dev/null
+++ b/tools/aconfig/aconfig/tests/storage_test_4.values
@@ -0,0 +1,12 @@
+flag_value {
+    package: "com.android.aconfig.storage.test_4"
+    name: "enabled_ro"
+    state: ENABLED
+    permission: READ_ONLY
+}
+flag_value {
+    package: "com.android.aconfig.storage.test_4"
+    name: "enabled_fixed_ro"
+    state: ENABLED
+    permission: READ_ONLY
+}
diff --git a/tools/aconfig/aconfig_storage_file/src/flag_info.rs b/tools/aconfig/aconfig_storage_file/src/flag_info.rs
index 6ece543..3fff263 100644
--- a/tools/aconfig/aconfig_storage_file/src/flag_info.rs
+++ b/tools/aconfig/aconfig_storage_file/src/flag_info.rs
@@ -55,7 +55,7 @@
 
 impl FlagInfoHeader {
     /// Serialize to bytes
-    pub fn as_bytes(&self) -> Vec<u8> {
+    pub fn into_bytes(&self) -> Vec<u8> {
         let mut result = Vec::new();
         result.extend_from_slice(&self.version.to_le_bytes());
         let container_bytes = self.container.as_bytes();
@@ -118,7 +118,7 @@
 
 impl FlagInfoNode {
     /// Serialize to bytes
-    pub fn as_bytes(&self) -> Vec<u8> {
+    pub fn into_bytes(&self) -> Vec<u8> {
         let mut result = Vec::new();
         result.extend_from_slice(&self.attributes.to_le_bytes());
         result
@@ -130,6 +130,11 @@
         let node = Self { attributes: read_u8_from_bytes(bytes, &mut head)? };
         Ok(node)
     }
+
+    /// Create flag info node
+    pub fn create(is_flag_rw: bool) -> Self {
+        Self { attributes: if is_flag_rw { FlagInfoBit::IsReadWrite as u8 } else { 0u8 } }
+    }
 }
 
 /// Flag info list struct
@@ -154,10 +159,10 @@
 
 impl FlagInfoList {
     /// Serialize to bytes
-    pub fn as_bytes(&self) -> Vec<u8> {
+    pub fn into_bytes(&self) -> Vec<u8> {
         [
-            self.header.as_bytes(),
-            self.nodes.iter().map(|v| v.as_bytes()).collect::<Vec<_>>().concat(),
+            self.header.into_bytes(),
+            self.nodes.iter().map(|v| v.into_bytes()).collect::<Vec<_>>().concat(),
         ]
         .concat()
     }
@@ -166,11 +171,11 @@
     pub fn from_bytes(bytes: &[u8]) -> Result<Self, AconfigStorageError> {
         let header = FlagInfoHeader::from_bytes(bytes)?;
         let num_flags = header.num_flags;
-        let mut head = header.as_bytes().len();
+        let mut head = header.into_bytes().len();
         let nodes = (0..num_flags)
             .map(|_| {
                 let node = FlagInfoNode::from_bytes(&bytes[head..])?;
-                head += node.as_bytes().len();
+                head += node.into_bytes().len();
                 Ok(node)
             })
             .collect::<Result<Vec<_>, AconfigStorageError>>()
@@ -196,17 +201,17 @@
         let flag_info_list = create_test_flag_info_list();
 
         let header: &FlagInfoHeader = &flag_info_list.header;
-        let reinterpreted_header = FlagInfoHeader::from_bytes(&header.as_bytes());
+        let reinterpreted_header = FlagInfoHeader::from_bytes(&header.into_bytes());
         assert!(reinterpreted_header.is_ok());
         assert_eq!(header, &reinterpreted_header.unwrap());
 
         let nodes: &Vec<FlagInfoNode> = &flag_info_list.nodes;
         for node in nodes.iter() {
-            let reinterpreted_node = FlagInfoNode::from_bytes(&node.as_bytes()).unwrap();
+            let reinterpreted_node = FlagInfoNode::from_bytes(&node.into_bytes()).unwrap();
             assert_eq!(node, &reinterpreted_node);
         }
 
-        let flag_info_bytes = flag_info_list.as_bytes();
+        let flag_info_bytes = flag_info_list.into_bytes();
         let reinterpreted_info_list = FlagInfoList::from_bytes(&flag_info_bytes);
         assert!(reinterpreted_info_list.is_ok());
         assert_eq!(&flag_info_list, &reinterpreted_info_list.unwrap());
@@ -218,10 +223,10 @@
     // bytes
     fn test_version_number() {
         let flag_info_list = create_test_flag_info_list();
-        let bytes = &flag_info_list.as_bytes();
+        let bytes = &flag_info_list.into_bytes();
         let mut head = 0;
         let version = read_u32_from_bytes(bytes, &mut head).unwrap();
-        assert_eq!(version, 1234)
+        assert_eq!(version, 1);
     }
 
     #[test]
@@ -229,7 +234,7 @@
     fn test_file_type_check() {
         let mut flag_info_list = create_test_flag_info_list();
         flag_info_list.header.file_type = 123u8;
-        let error = FlagInfoList::from_bytes(&flag_info_list.as_bytes()).unwrap_err();
+        let error = FlagInfoList::from_bytes(&flag_info_list.into_bytes()).unwrap_err();
         assert_eq!(
             format!("{:?}", error),
             format!("BytesParseFail(binary file is not a flag info file)")
diff --git a/tools/aconfig/aconfig_storage_file/src/flag_table.rs b/tools/aconfig/aconfig_storage_file/src/flag_table.rs
index f9b3158..f41f4ce 100644
--- a/tools/aconfig/aconfig_storage_file/src/flag_table.rs
+++ b/tools/aconfig/aconfig_storage_file/src/flag_table.rs
@@ -21,7 +21,7 @@
     get_bucket_index, read_str_from_bytes, read_u16_from_bytes, read_u32_from_bytes,
     read_u8_from_bytes,
 };
-use crate::{AconfigStorageError, StorageFileType};
+use crate::{AconfigStorageError, StorageFileType, StoredFlagType};
 use anyhow::anyhow;
 use std::fmt;
 
@@ -59,7 +59,7 @@
 
 impl FlagTableHeader {
     /// Serialize to bytes
-    pub fn as_bytes(&self) -> Vec<u8> {
+    pub fn into_bytes(&self) -> Vec<u8> {
         let mut result = Vec::new();
         result.extend_from_slice(&self.version.to_le_bytes());
         let container_bytes = self.container.as_bytes();
@@ -99,7 +99,7 @@
 pub struct FlagTableNode {
     pub package_id: u32,
     pub flag_name: String,
-    pub flag_type: u16,
+    pub flag_type: StoredFlagType,
     pub flag_id: u16,
     pub next_offset: Option<u32>,
 }
@@ -109,7 +109,7 @@
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         writeln!(
             f,
-            "Package Id: {}, Flag: {}, Type: {}, Offset: {}, Next: {:?}",
+            "Package Id: {}, Flag: {}, Type: {:?}, Offset: {}, Next: {:?}",
             self.package_id, self.flag_name, self.flag_type, self.flag_id, self.next_offset
         )?;
         Ok(())
@@ -118,13 +118,13 @@
 
 impl FlagTableNode {
     /// Serialize to bytes
-    pub fn as_bytes(&self) -> Vec<u8> {
+    pub fn into_bytes(&self) -> Vec<u8> {
         let mut result = Vec::new();
         result.extend_from_slice(&self.package_id.to_le_bytes());
         let name_bytes = self.flag_name.as_bytes();
         result.extend_from_slice(&(name_bytes.len() as u32).to_le_bytes());
         result.extend_from_slice(name_bytes);
-        result.extend_from_slice(&self.flag_type.to_le_bytes());
+        result.extend_from_slice(&(self.flag_type as u16).to_le_bytes());
         result.extend_from_slice(&self.flag_id.to_le_bytes());
         result.extend_from_slice(&self.next_offset.unwrap_or(0).to_le_bytes());
         result
@@ -136,7 +136,7 @@
         let node = Self {
             package_id: read_u32_from_bytes(bytes, &mut head)?,
             flag_name: read_str_from_bytes(bytes, &mut head)?,
-            flag_type: read_u16_from_bytes(bytes, &mut head)?,
+            flag_type: StoredFlagType::try_from(read_u16_from_bytes(bytes, &mut head)?)?,
             flag_id: read_u16_from_bytes(bytes, &mut head)?,
             next_offset: match read_u32_from_bytes(bytes, &mut head)? {
                 0 => None,
@@ -178,11 +178,11 @@
 /// Flag table struct
 impl FlagTable {
     /// Serialize to bytes
-    pub fn as_bytes(&self) -> Vec<u8> {
+    pub fn into_bytes(&self) -> Vec<u8> {
         [
-            self.header.as_bytes(),
+            self.header.into_bytes(),
             self.buckets.iter().map(|v| v.unwrap_or(0).to_le_bytes()).collect::<Vec<_>>().concat(),
-            self.nodes.iter().map(|v| v.as_bytes()).collect::<Vec<_>>().concat(),
+            self.nodes.iter().map(|v| v.into_bytes()).collect::<Vec<_>>().concat(),
         ]
         .concat()
     }
@@ -192,7 +192,7 @@
         let header = FlagTableHeader::from_bytes(bytes)?;
         let num_flags = header.num_flags;
         let num_buckets = crate::get_table_size(num_flags)?;
-        let mut head = header.as_bytes().len();
+        let mut head = header.into_bytes().len();
         let buckets = (0..num_buckets)
             .map(|_| match read_u32_from_bytes(bytes, &mut head).unwrap() {
                 0 => None,
@@ -202,7 +202,7 @@
         let nodes = (0..num_flags)
             .map(|_| {
                 let node = FlagTableNode::from_bytes(&bytes[head..])?;
-                head += node.as_bytes().len();
+                head += node.into_bytes().len();
                 Ok(node)
             })
             .collect::<Result<Vec<_>, AconfigStorageError>>()
@@ -226,17 +226,17 @@
         let flag_table = create_test_flag_table();
 
         let header: &FlagTableHeader = &flag_table.header;
-        let reinterpreted_header = FlagTableHeader::from_bytes(&header.as_bytes());
+        let reinterpreted_header = FlagTableHeader::from_bytes(&header.into_bytes());
         assert!(reinterpreted_header.is_ok());
         assert_eq!(header, &reinterpreted_header.unwrap());
 
         let nodes: &Vec<FlagTableNode> = &flag_table.nodes;
         for node in nodes.iter() {
-            let reinterpreted_node = FlagTableNode::from_bytes(&node.as_bytes()).unwrap();
+            let reinterpreted_node = FlagTableNode::from_bytes(&node.into_bytes()).unwrap();
             assert_eq!(node, &reinterpreted_node);
         }
 
-        let flag_table_bytes = flag_table.as_bytes();
+        let flag_table_bytes = flag_table.into_bytes();
         let reinterpreted_table = FlagTable::from_bytes(&flag_table_bytes);
         assert!(reinterpreted_table.is_ok());
         assert_eq!(&flag_table, &reinterpreted_table.unwrap());
@@ -248,10 +248,10 @@
     // bytes
     fn test_version_number() {
         let flag_table = create_test_flag_table();
-        let bytes = &flag_table.as_bytes();
+        let bytes = &flag_table.into_bytes();
         let mut head = 0;
         let version = read_u32_from_bytes(bytes, &mut head).unwrap();
-        assert_eq!(version, 1234)
+        assert_eq!(version, 1);
     }
 
     #[test]
@@ -259,7 +259,7 @@
     fn test_file_type_check() {
         let mut flag_table = create_test_flag_table();
         flag_table.header.file_type = 123u8;
-        let error = FlagTable::from_bytes(&flag_table.as_bytes()).unwrap_err();
+        let error = FlagTable::from_bytes(&flag_table.into_bytes()).unwrap_err();
         assert_eq!(
             format!("{:?}", error),
             format!("BytesParseFail(binary file is not a flag map)")
diff --git a/tools/aconfig/aconfig_storage_file/src/flag_value.rs b/tools/aconfig/aconfig_storage_file/src/flag_value.rs
index c9d09a1..506924b 100644
--- a/tools/aconfig/aconfig_storage_file/src/flag_value.rs
+++ b/tools/aconfig/aconfig_storage_file/src/flag_value.rs
@@ -55,7 +55,7 @@
 
 impl FlagValueHeader {
     /// Serialize to bytes
-    pub fn as_bytes(&self) -> Vec<u8> {
+    pub fn into_bytes(&self) -> Vec<u8> {
         let mut result = Vec::new();
         result.extend_from_slice(&self.version.to_le_bytes());
         let container_bytes = self.container.as_bytes();
@@ -108,9 +108,9 @@
 
 impl FlagValueList {
     /// Serialize to bytes
-    pub fn as_bytes(&self) -> Vec<u8> {
+    pub fn into_bytes(&self) -> Vec<u8> {
         [
-            self.header.as_bytes(),
+            self.header.into_bytes(),
             self.booleans.iter().map(|&v| u8::from(v).to_le_bytes()).collect::<Vec<_>>().concat(),
         ]
         .concat()
@@ -120,7 +120,7 @@
     pub fn from_bytes(bytes: &[u8]) -> Result<Self, AconfigStorageError> {
         let header = FlagValueHeader::from_bytes(bytes)?;
         let num_flags = header.num_flags;
-        let mut head = header.as_bytes().len();
+        let mut head = header.into_bytes().len();
         let booleans =
             (0..num_flags).map(|_| read_u8_from_bytes(bytes, &mut head).unwrap() == 1).collect();
         let list = Self { header, booleans };
@@ -139,11 +139,11 @@
         let flag_value_list = create_test_flag_value_list();
 
         let header: &FlagValueHeader = &flag_value_list.header;
-        let reinterpreted_header = FlagValueHeader::from_bytes(&header.as_bytes());
+        let reinterpreted_header = FlagValueHeader::from_bytes(&header.into_bytes());
         assert!(reinterpreted_header.is_ok());
         assert_eq!(header, &reinterpreted_header.unwrap());
 
-        let flag_value_bytes = flag_value_list.as_bytes();
+        let flag_value_bytes = flag_value_list.into_bytes();
         let reinterpreted_value_list = FlagValueList::from_bytes(&flag_value_bytes);
         assert!(reinterpreted_value_list.is_ok());
         assert_eq!(&flag_value_list, &reinterpreted_value_list.unwrap());
@@ -155,10 +155,10 @@
     // bytes
     fn test_version_number() {
         let flag_value_list = create_test_flag_value_list();
-        let bytes = &flag_value_list.as_bytes();
+        let bytes = &flag_value_list.into_bytes();
         let mut head = 0;
         let version = read_u32_from_bytes(bytes, &mut head).unwrap();
-        assert_eq!(version, 1234)
+        assert_eq!(version, 1);
     }
 
     #[test]
@@ -166,7 +166,7 @@
     fn test_file_type_check() {
         let mut flag_value_list = create_test_flag_value_list();
         flag_value_list.header.file_type = 123u8;
-        let error = FlagValueList::from_bytes(&flag_value_list.as_bytes()).unwrap_err();
+        let error = FlagValueList::from_bytes(&flag_value_list.into_bytes()).unwrap_err();
         assert_eq!(
             format!("{:?}", error),
             format!("BytesParseFail(binary file is not a flag value file)")
diff --git a/tools/aconfig/aconfig_storage_file/src/lib.rs b/tools/aconfig/aconfig_storage_file/src/lib.rs
index 50ac69d..3b975d9 100644
--- a/tools/aconfig/aconfig_storage_file/src/lib.rs
+++ b/tools/aconfig/aconfig_storage_file/src/lib.rs
@@ -37,22 +37,23 @@
 pub mod flag_value;
 pub mod package_table;
 pub mod protos;
-
-#[cfg(test)]
-mod test_utils;
+pub mod test_utils;
 
 use anyhow::anyhow;
+use std::cmp::Ordering;
 use std::collections::hash_map::DefaultHasher;
 use std::fs::File;
 use std::hash::{Hash, Hasher};
-use std::io::Read;
+use std::io::{Read, Write};
 
 pub use crate::flag_info::{FlagInfoHeader, FlagInfoList, FlagInfoNode};
 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, HashTableSizeLimit};
+use crate::AconfigStorageError::{
+    BytesParseFail, FileCreationFail, HashTableSizeLimit, InvalidStoredFlagType,
+};
 
 /// Storage file version
 pub const FILE_VERSION: u32 = 1;
@@ -83,7 +84,7 @@
             "flag_val" => Ok(Self::FlagVal),
             "flag_info" => Ok(Self::FlagInfo),
             _ => Err(anyhow!(
-                "Invalid storage file type, valid types are package_map|flag_map|flag_val"
+                "Invalid storage file type, valid types are package_map|flag_map|flag_val|flag_info"
             )),
         }
     }
@@ -103,6 +104,68 @@
     }
 }
 
+/// Flag type enum as stored by storage file
+#[derive(Clone, Copy, Debug, PartialEq, Eq)]
+pub enum StoredFlagType {
+    ReadWriteBoolean = 0,
+    ReadOnlyBoolean = 1,
+    FixedReadOnlyBoolean = 2,
+}
+
+impl TryFrom<u16> for StoredFlagType {
+    type Error = AconfigStorageError;
+
+    fn try_from(value: u16) -> Result<Self, Self::Error> {
+        match value {
+            x if x == Self::ReadWriteBoolean as u16 => Ok(Self::ReadWriteBoolean),
+            x if x == Self::ReadOnlyBoolean as u16 => Ok(Self::ReadOnlyBoolean),
+            x if x == Self::FixedReadOnlyBoolean as u16 => Ok(Self::FixedReadOnlyBoolean),
+            _ => Err(InvalidStoredFlagType(anyhow!("Invalid stored flag type"))),
+        }
+    }
+}
+
+/// Storage query api error
+#[non_exhaustive]
+#[derive(thiserror::Error, Debug)]
+pub enum AconfigStorageError {
+    #[error("failed to read the file")]
+    FileReadFail(#[source] anyhow::Error),
+
+    #[error("fail to parse protobuf")]
+    ProtobufParseFail(#[source] anyhow::Error),
+
+    #[error("storage files not found for this container")]
+    StorageFileNotFound(#[source] anyhow::Error),
+
+    #[error("fail to map storage file")]
+    MapFileFail(#[source] anyhow::Error),
+
+    #[error("fail to get mapped file")]
+    ObtainMappedFileFail(#[source] anyhow::Error),
+
+    #[error("fail to flush mapped storage file")]
+    MapFlushFail(#[source] anyhow::Error),
+
+    #[error("number of items in hash table exceed limit")]
+    HashTableSizeLimit(#[source] anyhow::Error),
+
+    #[error("failed to parse bytes into data")]
+    BytesParseFail(#[source] anyhow::Error),
+
+    #[error("cannot parse storage files with a higher version")]
+    HigherStorageFileVersion(#[source] anyhow::Error),
+
+    #[error("invalid storage file byte offset")]
+    InvalidStorageFileOffset(#[source] anyhow::Error),
+
+    #[error("failed to create file")]
+    FileCreationFail(#[source] anyhow::Error),
+
+    #[error("invalid stored flag type")]
+    InvalidStoredFlagType(#[source] anyhow::Error),
+}
+
 /// Get the right hash table size given number of entries in the table. Use a
 /// load factor of 0.5 for performance.
 pub fn get_table_size(entries: u32) -> Result<u32, AconfigStorageError> {
@@ -165,44 +228,6 @@
     Ok(val)
 }
 
-/// Storage query api error
-#[non_exhaustive]
-#[derive(thiserror::Error, Debug)]
-pub enum AconfigStorageError {
-    #[error("failed to read the file")]
-    FileReadFail(#[source] anyhow::Error),
-
-    #[error("fail to parse protobuf")]
-    ProtobufParseFail(#[source] anyhow::Error),
-
-    #[error("storage files not found for this container")]
-    StorageFileNotFound(#[source] anyhow::Error),
-
-    #[error("fail to map storage file")]
-    MapFileFail(#[source] anyhow::Error),
-
-    #[error("fail to get mapped file")]
-    ObtainMappedFileFail(#[source] anyhow::Error),
-
-    #[error("fail to flush mapped storage file")]
-    MapFlushFail(#[source] anyhow::Error),
-
-    #[error("number of items in hash table exceed limit")]
-    HashTableSizeLimit(#[source] anyhow::Error),
-
-    #[error("failed to parse bytes into data")]
-    BytesParseFail(#[source] anyhow::Error),
-
-    #[error("cannot parse storage files with a higher version")]
-    HigherStorageFileVersion(#[source] anyhow::Error),
-
-    #[error("invalid storage file byte offset")]
-    InvalidStorageFileOffset(#[source] anyhow::Error),
-
-    #[error("failed to create file")]
-    FileCreationFail(#[source] anyhow::Error),
-}
-
 /// Read in storage file as bytes
 pub fn read_file_to_bytes(file_path: &str) -> Result<Vec<u8>, AconfigStorageError> {
     let mut file = File::open(file_path).map_err(|errmsg| {
@@ -211,7 +236,7 @@
     let mut buffer = Vec::new();
     file.read_to_end(&mut buffer).map_err(|errmsg| {
         AconfigStorageError::FileReadFail(anyhow!(
-            "Failed to read 4 bytes from file {}: {}",
+            "Failed to read bytes from file {}: {}",
             file_path,
             errmsg
         ))
@@ -224,7 +249,7 @@
     package_map: &str,
     flag_map: &str,
     flag_val: &str,
-) -> Result<Vec<(String, String, bool)>, AconfigStorageError> {
+) -> Result<Vec<(String, String, StoredFlagType, bool)>, 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)?)?;
     let flag_value_list = FlagValueList::from_bytes(&read_file_to_bytes(flag_val)?)?;
@@ -239,29 +264,91 @@
         let (package_name, package_offset) = package_info[node.package_id as usize];
         let flag_offset = package_offset + node.flag_id as u32;
         let flag_value = flag_value_list.booleans[flag_offset as usize];
-        flags.push((String::from(package_name), node.flag_name.clone(), flag_value));
+        flags.push((
+            String::from(package_name),
+            node.flag_name.clone(),
+            node.flag_type,
+            flag_value,
+        ));
     }
 
-    flags.sort_by(|v1, v2| v1.0.cmp(&v2.0));
+    flags.sort_by(|v1, v2| match v1.0.cmp(&v2.0) {
+        Ordering::Equal => v1.1.cmp(&v2.1),
+        other => other,
+    });
     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_table, create_test_flag_value_list, create_test_package_table,
-        write_bytes_to_temp_file,
+        create_test_flag_info_list, 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
     fn test_list_flag() {
         let package_table =
-            write_bytes_to_temp_file(&create_test_package_table().as_bytes()).unwrap();
-        let flag_table = write_bytes_to_temp_file(&create_test_flag_table().as_bytes()).unwrap();
+            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_value_list =
-            write_bytes_to_temp_file(&create_test_flag_value_list().as_bytes()).unwrap();
+            write_bytes_to_temp_file(&create_test_flag_value_list().into_bytes()).unwrap();
 
         let package_table_path = package_table.path().display().to_string();
         let flag_table_path = flag_table.path().display().to_string();
@@ -270,31 +357,82 @@
         let flags =
             list_flags(&package_table_path, &flag_table_path, &flag_value_list_path).unwrap();
         let expected = [
-            (String::from("com.android.aconfig.storage.test_1"), String::from("enabled_ro"), true),
-            (String::from("com.android.aconfig.storage.test_1"), String::from("enabled_rw"), false),
             (
                 String::from("com.android.aconfig.storage.test_1"),
                 String::from("disabled_rw"),
+                StoredFlagType::ReadWriteBoolean,
                 false,
             ),
             (
+                String::from("com.android.aconfig.storage.test_1"),
+                String::from("enabled_ro"),
+                StoredFlagType::ReadOnlyBoolean,
+                true,
+            ),
+            (
+                String::from("com.android.aconfig.storage.test_1"),
+                String::from("enabled_rw"),
+                StoredFlagType::ReadWriteBoolean,
+                true,
+            ),
+            (
                 String::from("com.android.aconfig.storage.test_2"),
                 String::from("disabled_ro"),
+                StoredFlagType::ReadOnlyBoolean,
                 false,
             ),
             (
                 String::from("com.android.aconfig.storage.test_2"),
                 String::from("enabled_fixed_ro"),
+                StoredFlagType::FixedReadOnlyBoolean,
                 true,
             ),
-            (String::from("com.android.aconfig.storage.test_2"), String::from("enabled_ro"), true),
-            (String::from("com.android.aconfig.storage.test_4"), String::from("enabled_ro"), true),
+            (
+                String::from("com.android.aconfig.storage.test_2"),
+                String::from("enabled_ro"),
+                StoredFlagType::ReadOnlyBoolean,
+                true,
+            ),
             (
                 String::from("com.android.aconfig.storage.test_4"),
                 String::from("enabled_fixed_ro"),
-                false,
+                StoredFlagType::FixedReadOnlyBoolean,
+                true,
+            ),
+            (
+                String::from("com.android.aconfig.storage.test_4"),
+                String::from("enabled_ro"),
+                StoredFlagType::ReadOnlyBoolean,
+                true,
             ),
         ];
         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_file/src/main.rs b/tools/aconfig/aconfig_storage_file/src/main.rs
index 12e0024..b686274 100644
--- a/tools/aconfig/aconfig_storage_file/src/main.rs
+++ b/tools/aconfig/aconfig_storage_file/src/main.rs
@@ -88,8 +88,8 @@
             let flag_map = sub_matches.get_one::<String>("flag-map").unwrap();
             let flag_val = sub_matches.get_one::<String>("flag-val").unwrap();
             let flags = list_flags(package_map, flag_map, flag_val)?;
-            for flag in flags.iter() {
-                println!("{}: {}", flag.0, flag.1);
+            for (package_name, flag_name, flag_type, flag_value) in flags.iter() {
+                println!("{} {} {:?} {}", package_name, flag_name, flag_type, flag_value);
             }
         }
         _ => unreachable!(),
diff --git a/tools/aconfig/aconfig_storage_file/src/package_table.rs b/tools/aconfig/aconfig_storage_file/src/package_table.rs
index 7cb60eb..36b0493 100644
--- a/tools/aconfig/aconfig_storage_file/src/package_table.rs
+++ b/tools/aconfig/aconfig_storage_file/src/package_table.rs
@@ -56,7 +56,7 @@
 
 impl PackageTableHeader {
     /// Serialize to bytes
-    pub fn as_bytes(&self) -> Vec<u8> {
+    pub fn into_bytes(&self) -> Vec<u8> {
         let mut result = Vec::new();
         result.extend_from_slice(&self.version.to_le_bytes());
         let container_bytes = self.container.as_bytes();
@@ -116,7 +116,7 @@
 
 impl PackageTableNode {
     /// Serialize to bytes
-    pub fn as_bytes(&self) -> Vec<u8> {
+    pub fn into_bytes(&self) -> Vec<u8> {
         let mut result = Vec::new();
         let name_bytes = self.package_name.as_bytes();
         result.extend_from_slice(&(name_bytes.len() as u32).to_le_bytes());
@@ -175,11 +175,11 @@
 
 impl PackageTable {
     /// Serialize to bytes
-    pub fn as_bytes(&self) -> Vec<u8> {
+    pub fn into_bytes(&self) -> Vec<u8> {
         [
-            self.header.as_bytes(),
+            self.header.into_bytes(),
             self.buckets.iter().map(|v| v.unwrap_or(0).to_le_bytes()).collect::<Vec<_>>().concat(),
-            self.nodes.iter().map(|v| v.as_bytes()).collect::<Vec<_>>().concat(),
+            self.nodes.iter().map(|v| v.into_bytes()).collect::<Vec<_>>().concat(),
         ]
         .concat()
     }
@@ -189,7 +189,7 @@
         let header = PackageTableHeader::from_bytes(bytes)?;
         let num_packages = header.num_packages;
         let num_buckets = crate::get_table_size(num_packages)?;
-        let mut head = header.as_bytes().len();
+        let mut head = header.into_bytes().len();
         let buckets = (0..num_buckets)
             .map(|_| match read_u32_from_bytes(bytes, &mut head).unwrap() {
                 0 => None,
@@ -199,7 +199,7 @@
         let nodes = (0..num_packages)
             .map(|_| {
                 let node = PackageTableNode::from_bytes(&bytes[head..])?;
-                head += node.as_bytes().len();
+                head += node.into_bytes().len();
                 Ok(node)
             })
             .collect::<Result<Vec<_>, AconfigStorageError>>()
@@ -225,17 +225,17 @@
     fn test_serialization() {
         let package_table = create_test_package_table();
         let header: &PackageTableHeader = &package_table.header;
-        let reinterpreted_header = PackageTableHeader::from_bytes(&header.as_bytes());
+        let reinterpreted_header = PackageTableHeader::from_bytes(&header.into_bytes());
         assert!(reinterpreted_header.is_ok());
         assert_eq!(header, &reinterpreted_header.unwrap());
 
         let nodes: &Vec<PackageTableNode> = &package_table.nodes;
         for node in nodes.iter() {
-            let reinterpreted_node = PackageTableNode::from_bytes(&node.as_bytes()).unwrap();
+            let reinterpreted_node = PackageTableNode::from_bytes(&node.into_bytes()).unwrap();
             assert_eq!(node, &reinterpreted_node);
         }
 
-        let package_table_bytes = package_table.as_bytes();
+        let package_table_bytes = package_table.into_bytes();
         let reinterpreted_table = PackageTable::from_bytes(&package_table_bytes);
         assert!(reinterpreted_table.is_ok());
         assert_eq!(&package_table, &reinterpreted_table.unwrap());
@@ -247,10 +247,10 @@
     // bytes
     fn test_version_number() {
         let package_table = create_test_package_table();
-        let bytes = &package_table.as_bytes();
+        let bytes = &package_table.into_bytes();
         let mut head = 0;
         let version = read_u32_from_bytes(bytes, &mut head).unwrap();
-        assert_eq!(version, 1234)
+        assert_eq!(version, 1);
     }
 
     #[test]
@@ -258,7 +258,7 @@
     fn test_file_type_check() {
         let mut package_table = create_test_package_table();
         package_table.header.file_type = 123u8;
-        let error = PackageTable::from_bytes(&package_table.as_bytes()).unwrap_err();
+        let error = PackageTable::from_bytes(&package_table.into_bytes()).unwrap_err();
         assert_eq!(
             format!("{:?}", error),
             format!("BytesParseFail(binary file is not a package map)")
diff --git a/tools/aconfig/aconfig_storage_file/src/test_utils.rs b/tools/aconfig/aconfig_storage_file/src/test_utils.rs
index 4641829..c0f647a 100644
--- a/tools/aconfig/aconfig_storage_file/src/test_utils.rs
+++ b/tools/aconfig/aconfig_storage_file/src/test_utils.rs
@@ -18,16 +18,16 @@
 use crate::flag_table::{FlagTable, FlagTableHeader, FlagTableNode};
 use crate::flag_value::{FlagValueHeader, FlagValueList};
 use crate::package_table::{PackageTable, PackageTableHeader, PackageTableNode};
-use crate::{AconfigStorageError, StorageFileType};
+use crate::{AconfigStorageError, StorageFileType, StoredFlagType};
 
 use anyhow::anyhow;
 use std::io::Write;
 use tempfile::NamedTempFile;
 
-pub(crate) fn create_test_package_table() -> PackageTable {
+pub fn create_test_package_table() -> PackageTable {
     let header = PackageTableHeader {
-        version: 1234,
-        container: String::from("system"),
+        version: 1,
+        container: String::from("mockup"),
         file_type: StorageFileType::PackageMap as u8,
         file_size: 209,
         num_packages: 3,
@@ -66,14 +66,20 @@
         flag_id: u16,
         next_offset: Option<u32>,
     ) -> Self {
-        Self { package_id, flag_name: flag_name.to_string(), flag_type, flag_id, next_offset }
+        Self {
+            package_id,
+            flag_name: flag_name.to_string(),
+            flag_type: StoredFlagType::try_from(flag_type).unwrap(),
+            flag_id,
+            next_offset,
+        }
     }
 }
 
-pub(crate) fn create_test_flag_table() -> FlagTable {
+pub fn create_test_flag_table() -> FlagTable {
     let header = FlagTableHeader {
-        version: 1234,
-        container: String::from("system"),
+        version: 1,
+        container: String::from("mockup"),
         file_type: StorageFileType::FlagMap as u8,
         file_size: 321,
         num_flags: 8,
@@ -101,44 +107,45 @@
     ];
     let nodes = vec![
         FlagTableNode::new_expected(0, "enabled_ro", 1, 1, None),
-        FlagTableNode::new_expected(0, "enabled_rw", 1, 2, Some(151)),
+        FlagTableNode::new_expected(0, "enabled_rw", 0, 2, Some(151)),
         FlagTableNode::new_expected(1, "disabled_ro", 1, 0, None),
         FlagTableNode::new_expected(2, "enabled_ro", 1, 1, None),
-        FlagTableNode::new_expected(1, "enabled_fixed_ro", 1, 1, Some(236)),
+        FlagTableNode::new_expected(1, "enabled_fixed_ro", 2, 1, Some(236)),
         FlagTableNode::new_expected(1, "enabled_ro", 1, 2, None),
-        FlagTableNode::new_expected(2, "enabled_fixed_ro", 1, 0, None),
-        FlagTableNode::new_expected(0, "disabled_rw", 1, 0, None),
+        FlagTableNode::new_expected(2, "enabled_fixed_ro", 2, 0, None),
+        FlagTableNode::new_expected(0, "disabled_rw", 0, 0, None),
     ];
     FlagTable { header, buckets, nodes }
 }
 
-pub(crate) fn create_test_flag_value_list() -> FlagValueList {
+pub fn create_test_flag_value_list() -> FlagValueList {
     let header = FlagValueHeader {
-        version: 1234,
-        container: String::from("system"),
+        version: 1,
+        container: String::from("mockup"),
         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];
+    let booleans: Vec<bool> = vec![false, true, true, false, true, true, true, true];
     FlagValueList { header, booleans }
 }
 
-pub(crate) fn create_test_flag_info_list() -> FlagInfoList {
+pub fn create_test_flag_info_list() -> FlagInfoList {
     let header = FlagInfoHeader {
-        version: 1234,
-        container: String::from("system"),
+        version: 1,
+        container: String::from("mockup"),
         file_type: StorageFileType::FlagInfo as u8,
         file_size: 35,
         num_flags: 8,
         boolean_flag_offset: 27,
     };
-    let nodes: Vec<FlagInfoNode> = vec![FlagInfoNode { attributes: 0 }; 8];
+    let is_flag_rw = [true, false, true, false, false, false, false, false];
+    let nodes = is_flag_rw.iter().map(|&rw| FlagInfoNode::create(rw)).collect();
     FlagInfoList { header, nodes }
 }
 
-pub(crate) fn write_bytes_to_temp_file(bytes: &[u8]) -> Result<NamedTempFile, AconfigStorageError> {
+pub fn write_bytes_to_temp_file(bytes: &[u8]) -> Result<NamedTempFile, AconfigStorageError> {
     let mut file = NamedTempFile::new().map_err(|_| {
         AconfigStorageError::FileCreationFail(anyhow!("Failed to create temp file"))
     })?;
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 43977ee..a251b41 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
@@ -65,71 +65,12 @@
 #[cfg(test)]
 mod tests {
     use super::*;
-    use aconfig_storage_file::{FlagTable, StorageFileType};
-
-    // create test baseline, syntactic sugar
-    fn new_expected_node(
-        package_id: u32,
-        flag_name: &str,
-        flag_type: u16,
-        flag_id: u16,
-        next_offset: Option<u32>,
-    ) -> FlagTableNode {
-        FlagTableNode {
-            package_id,
-            flag_name: flag_name.to_string(),
-            flag_type,
-            flag_id,
-            next_offset,
-        }
-    }
-
-    pub fn create_test_flag_table() -> FlagTable {
-        let header = FlagTableHeader {
-            version: crate::FILE_VERSION,
-            container: String::from("system"),
-            file_type: StorageFileType::FlagMap as u8,
-            file_size: 321,
-            num_flags: 8,
-            bucket_offset: 31,
-            node_offset: 99,
-        };
-        let buckets: Vec<Option<u32>> = vec![
-            Some(99),
-            Some(125),
-            None,
-            None,
-            None,
-            Some(178),
-            None,
-            Some(204),
-            None,
-            Some(262),
-            None,
-            None,
-            None,
-            None,
-            None,
-            Some(294),
-            None,
-        ];
-        let nodes = vec![
-            new_expected_node(0, "enabled_ro", 1, 1, None),
-            new_expected_node(0, "enabled_rw", 1, 2, Some(151)),
-            new_expected_node(1, "disabled_ro", 1, 0, None),
-            new_expected_node(2, "enabled_ro", 1, 1, None),
-            new_expected_node(1, "enabled_fixed_ro", 1, 1, Some(236)),
-            new_expected_node(1, "enabled_ro", 1, 2, None),
-            new_expected_node(2, "enabled_fixed_ro", 1, 0, None),
-            new_expected_node(0, "disabled_rw", 1, 0, None),
-        ];
-        FlagTable { header, buckets, nodes }
-    }
+    use aconfig_storage_file::test_utils::create_test_flag_table;
 
     #[test]
     // this test point locks down table query
     fn test_flag_query() {
-        let flag_table = create_test_flag_table().as_bytes();
+        let flag_table = create_test_flag_table().into_bytes();
         let baseline = vec![
             (0, "enabled_ro", 1u16),
             (0, "enabled_rw", 2u16),
@@ -150,7 +91,7 @@
     #[test]
     // this test point locks down table query of a non exist flag
     fn test_not_existed_flag_query() {
-        let flag_table = create_test_flag_table().as_bytes();
+        let flag_table = create_test_flag_table().into_bytes();
         let flag_offset = find_flag_offset(&flag_table[..], 1, "disabled_fixed_ro").unwrap();
         assert_eq!(flag_offset, None);
         let flag_offset = find_flag_offset(&flag_table[..], 2, "disabled_rw").unwrap();
@@ -162,7 +103,7 @@
     fn test_higher_version_storage_file() {
         let mut table = create_test_flag_table();
         table.header.version = crate::FILE_VERSION + 1;
-        let flag_table = table.as_bytes();
+        let flag_table = table.into_bytes();
         let error = find_flag_offset(&flag_table[..], 0, "enabled_ro").unwrap_err();
         assert_eq!(
             format!("{:?}", error),
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 88d2397..964cd69 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
@@ -66,7 +66,7 @@
     #[test]
     // this test point locks down flag value query
     fn test_flag_value_query() {
-        let flag_value_list = create_test_flag_value_list().as_bytes();
+        let flag_value_list = create_test_flag_value_list().into_bytes();
         let baseline: Vec<bool> = vec![false, true, false, false, true, true, false, true];
         for (offset, expected_value) in baseline.into_iter().enumerate() {
             let flag_value = find_boolean_flag_value(&flag_value_list[..], offset as u32).unwrap();
@@ -77,7 +77,7 @@
     #[test]
     // this test point locks down query beyond the end of boolean section
     fn test_boolean_out_of_range() {
-        let flag_value_list = create_test_flag_value_list().as_bytes();
+        let flag_value_list = create_test_flag_value_list().into_bytes();
         let error = find_boolean_flag_value(&flag_value_list[..], 8).unwrap_err();
         assert_eq!(
             format!("{:?}", error),
@@ -90,7 +90,7 @@
     fn test_higher_version_storage_file() {
         let mut value_list = create_test_flag_value_list();
         value_list.header.version = crate::FILE_VERSION + 1;
-        let flag_value = value_list.as_bytes();
+        let flag_value = value_list.into_bytes();
         let error = find_boolean_flag_value(&flag_value[..], 4).unwrap_err();
         assert_eq!(
             format!("{:?}", error),
diff --git a/tools/aconfig/aconfig_storage_read_api/src/lib.rs b/tools/aconfig/aconfig_storage_read_api/src/lib.rs
index 8a71480..da64cb7 100644
--- a/tools/aconfig/aconfig_storage_read_api/src/lib.rs
+++ b/tools/aconfig/aconfig_storage_read_api/src/lib.rs
@@ -326,7 +326,7 @@
             r#"
 files {{
     version: 0
-    container: "system"
+    container: "mockup"
     package_map: "{}"
     flag_map: "{}"
     flag_val: "{}"
@@ -347,7 +347,7 @@
         let [_package_map, _flag_map, _flag_val, 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, "system", StorageFileType::PackageMap).unwrap()
+            get_mapped_file(&pb_file_path, "mockup", StorageFileType::PackageMap).unwrap()
         };
 
         let package_offset =
@@ -378,7 +378,7 @@
         let [_package_map, _flag_map, _flag_val, 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, "system", StorageFileType::FlagMap).unwrap() };
+            unsafe { get_mapped_file(&pb_file_path, "mockup", StorageFileType::FlagMap).unwrap() };
 
         let baseline = vec![
             (0, "enabled_ro", 1u16),
@@ -403,8 +403,8 @@
         let [_package_map, _flag_map, _flag_val, 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, "system", StorageFileType::FlagVal).unwrap() };
-        let baseline: Vec<bool> = vec![false; 8];
+            unsafe { get_mapped_file(&pb_file_path, "mockup", StorageFileType::FlagVal).unwrap() };
+        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 = get_boolean_flag_value(&flag_value_file, offset as u32).unwrap();
             assert_eq!(flag_value, expected_value);
diff --git a/tools/aconfig/aconfig_storage_read_api/src/package_table_query.rs b/tools/aconfig/aconfig_storage_read_api/src/package_table_query.rs
index 3587e10..d83844e 100644
--- a/tools/aconfig/aconfig_storage_read_api/src/package_table_query.rs
+++ b/tools/aconfig/aconfig_storage_read_api/src/package_table_query.rs
@@ -72,45 +72,12 @@
 #[cfg(test)]
 mod tests {
     use super::*;
-    use aconfig_storage_file::{PackageTable, StorageFileType};
-
-    pub fn create_test_package_table() -> PackageTable {
-        let header = PackageTableHeader {
-            version: crate::FILE_VERSION,
-            container: String::from("system"),
-            file_type: StorageFileType::PackageMap as u8,
-            file_size: 209,
-            num_packages: 3,
-            bucket_offset: 31,
-            node_offset: 59,
-        };
-        let buckets: Vec<Option<u32>> = vec![Some(59), None, None, Some(109), None, None, None];
-        let first_node = PackageTableNode {
-            package_name: String::from("com.android.aconfig.storage.test_2"),
-            package_id: 1,
-            boolean_offset: 3,
-            next_offset: None,
-        };
-        let second_node = PackageTableNode {
-            package_name: String::from("com.android.aconfig.storage.test_1"),
-            package_id: 0,
-            boolean_offset: 0,
-            next_offset: Some(159),
-        };
-        let third_node = PackageTableNode {
-            package_name: String::from("com.android.aconfig.storage.test_4"),
-            package_id: 2,
-            boolean_offset: 6,
-            next_offset: None,
-        };
-        let nodes = vec![first_node, second_node, third_node];
-        PackageTable { header, buckets, nodes }
-    }
+    use aconfig_storage_file::test_utils::create_test_package_table;
 
     #[test]
     // this test point locks down table query
     fn test_package_query() {
-        let package_table = create_test_package_table().as_bytes();
+        let package_table = create_test_package_table().into_bytes();
         let package_offset =
             find_package_offset(&package_table[..], "com.android.aconfig.storage.test_1")
                 .unwrap()
@@ -135,7 +102,7 @@
     // this test point locks down table query of a non exist package
     fn test_not_existed_package_query() {
         // this will land at an empty bucket
-        let package_table = create_test_package_table().as_bytes();
+        let package_table = create_test_package_table().into_bytes();
         let package_offset =
             find_package_offset(&package_table[..], "com.android.aconfig.storage.test_3").unwrap();
         assert_eq!(package_offset, None);
@@ -150,7 +117,7 @@
     fn test_higher_version_storage_file() {
         let mut table = create_test_package_table();
         table.header.version = crate::FILE_VERSION + 1;
-        let package_table = table.as_bytes();
+        let package_table = table.into_bytes();
         let error = find_package_offset(&package_table[..], "com.android.aconfig.storage.test_1")
             .unwrap_err();
         assert_eq!(
diff --git a/tools/aconfig/aconfig_storage_read_api/tests/flag.map b/tools/aconfig/aconfig_storage_read_api/tests/flag.map
index 5507894..d26e00f 100644
--- a/tools/aconfig/aconfig_storage_read_api/tests/flag.map
+++ b/tools/aconfig/aconfig_storage_read_api/tests/flag.map
Binary files differ
diff --git a/tools/aconfig/aconfig_storage_read_api/tests/flag.val b/tools/aconfig/aconfig_storage_read_api/tests/flag.val
index 75b8564..ed203d4 100644
--- a/tools/aconfig/aconfig_storage_read_api/tests/flag.val
+++ b/tools/aconfig/aconfig_storage_read_api/tests/flag.val
Binary files differ
diff --git a/tools/aconfig/aconfig_storage_read_api/tests/package.map b/tools/aconfig/aconfig_storage_read_api/tests/package.map
index 02267e5..6c46a03 100644
--- a/tools/aconfig/aconfig_storage_read_api/tests/package.map
+++ b/tools/aconfig/aconfig_storage_read_api/tests/package.map
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 1d36aae..539474b 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
@@ -52,7 +52,7 @@
     auto proto = storage_files();
     auto* info = proto.add_files();
     info->set_version(0);
-    info->set_container("system");
+    info->set_container("mockup");
     info->set_package_map(package_map);
     info->set_flag_map(flag_map);
     info->set_flag_val(flag_val);
@@ -113,7 +113,7 @@
 /// Test to lock down storage package offset query api
 TEST_F(AconfigStorageTest, test_package_offset_query) {
   auto mapped_file = private_api::get_mapped_file_impl(
-      storage_record_pb, "system", api::StorageFileType::package_map);
+      storage_record_pb, "mockup", api::StorageFileType::package_map);
   ASSERT_TRUE(mapped_file.ok());
 
   auto offset = api::get_package_offset(
@@ -141,7 +141,7 @@
 /// Test to lock down when querying none exist package
 TEST_F(AconfigStorageTest, test_none_existent_package_offset_query) {
   auto mapped_file = private_api::get_mapped_file_impl(
-      storage_record_pb, "system", api::StorageFileType::package_map);
+      storage_record_pb, "mockup", api::StorageFileType::package_map);
   ASSERT_TRUE(mapped_file.ok());
 
   auto offset = api::get_package_offset(
@@ -153,7 +153,7 @@
 /// Test to lock down storage flag offset query api
 TEST_F(AconfigStorageTest, test_flag_offset_query) {
   auto mapped_file = private_api::get_mapped_file_impl(
-      storage_record_pb, "system", api::StorageFileType::flag_map);
+      storage_record_pb, "mockup", api::StorageFileType::flag_map);
   ASSERT_TRUE(mapped_file.ok());
 
   auto baseline = std::vector<std::tuple<int, std::string, int>>{
@@ -177,7 +177,7 @@
 /// Test to lock down when querying none exist flag
 TEST_F(AconfigStorageTest, test_none_existent_flag_offset_query) {
   auto mapped_file = private_api::get_mapped_file_impl(
-      storage_record_pb, "system", api::StorageFileType::flag_map);
+      storage_record_pb, "mockup", api::StorageFileType::flag_map);
   ASSERT_TRUE(mapped_file.ok());
 
   auto offset = api::get_flag_offset(*mapped_file, 0, "none_exist");
@@ -192,20 +192,22 @@
 /// Test to lock down storage flag value query api
 TEST_F(AconfigStorageTest, test_boolean_flag_value_query) {
   auto mapped_file = private_api::get_mapped_file_impl(
-      storage_record_pb, "system", api::StorageFileType::flag_val);
+      storage_record_pb, "mockup", api::StorageFileType::flag_val);
   ASSERT_TRUE(mapped_file.ok());
 
+  auto expected_value = std::vector<bool>{
+    false, true, true, false, true, true, true, true};
   for (int offset = 0; offset < 8; ++offset) {
     auto value = api::get_boolean_flag_value(*mapped_file, offset);
     ASSERT_TRUE(value.ok());
-    ASSERT_FALSE(*value);
+    ASSERT_EQ(*value, expected_value[offset]);
   }
 }
 
 /// Negative test to lock down the error when querying flag value out of range
 TEST_F(AconfigStorageTest, test_invalid_boolean_flag_value_query) {
   auto mapped_file = private_api::get_mapped_file_impl(
-      storage_record_pb, "system", api::StorageFileType::flag_val);
+      storage_record_pb, "mockup", api::StorageFileType::flag_val);
   ASSERT_TRUE(mapped_file.ok());
 
   auto value = api::get_boolean_flag_value(*mapped_file, 8);
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 afcd5a7..7687d0f 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
@@ -24,7 +24,7 @@
             r#"
 files {{
     version: 0
-    container: "system"
+    container: "mockup"
     package_map: "{}"
     flag_map: "{}"
     flag_val: "{}"
@@ -61,7 +61,7 @@
         // SAFETY:
         // The safety here is ensured as the test process will not write to temp storage file
         let package_mapped_file = unsafe {
-            get_mapped_file(&pb_file_path, "system", StorageFileType::PackageMap).unwrap()
+            get_mapped_file(&pb_file_path, "mockup", StorageFileType::PackageMap).unwrap()
         };
 
         let package_offset =
@@ -93,7 +93,7 @@
         // SAFETY:
         // The safety here is ensured as the test process will not write to temp storage file
         let package_mapped_file = unsafe {
-            get_mapped_file(&pb_file_path, "system", StorageFileType::PackageMap).unwrap()
+            get_mapped_file(&pb_file_path, "mockup", StorageFileType::PackageMap).unwrap()
         };
 
         let package_offset_option =
@@ -108,7 +108,7 @@
         // SAFETY:
         // The safety here is ensured as the test process will not write to temp storage file
         let flag_mapped_file =
-            unsafe { get_mapped_file(&pb_file_path, "system", StorageFileType::FlagMap).unwrap() };
+            unsafe { get_mapped_file(&pb_file_path, "mockup", StorageFileType::FlagMap).unwrap() };
 
         let baseline = vec![
             (0, "enabled_ro", 1u16),
@@ -134,7 +134,7 @@
         // SAFETY:
         // The safety here is ensured as the test process will not write to temp storage file
         let flag_mapped_file =
-            unsafe { get_mapped_file(&pb_file_path, "system", StorageFileType::FlagMap).unwrap() };
+            unsafe { get_mapped_file(&pb_file_path, "mockup", StorageFileType::FlagMap).unwrap() };
         let flag_offset_option = get_flag_offset(&flag_mapped_file, 0, "none_exist").unwrap();
         assert_eq!(flag_offset_option, None);
 
@@ -149,8 +149,8 @@
         // SAFETY:
         // The safety here is ensured as the test process will not write to temp storage file
         let flag_value_file =
-            unsafe { get_mapped_file(&pb_file_path, "system", StorageFileType::FlagVal).unwrap() };
-        let baseline: Vec<bool> = vec![false; 8];
+            unsafe { get_mapped_file(&pb_file_path, "mockup", StorageFileType::FlagVal).unwrap() };
+        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 = get_boolean_flag_value(&flag_value_file, offset as u32).unwrap();
             assert_eq!(flag_value, expected_value);
@@ -164,7 +164,7 @@
         // SAFETY:
         // The safety here is ensured as the test process will not write to temp storage file
         let flag_value_file =
-            unsafe { get_mapped_file(&pb_file_path, "system", StorageFileType::FlagVal).unwrap() };
+            unsafe { get_mapped_file(&pb_file_path, "mockup", StorageFileType::FlagVal).unwrap() };
         let err = get_boolean_flag_value(&flag_value_file, 8u32).unwrap_err();
         assert_eq!(
             format!("{:?}", err),
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 e863c0e..e5155a4 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
@@ -62,7 +62,7 @@
   }
 
   if ((file_stat.st_mode & (S_IWUSR | S_IWGRP | S_IWOTH)) == 0) {
-    return ErrnoError() << "cannot map nonwriteable file";
+    return Error() << "cannot map nonwriteable file";
   }
 
   size_t file_size = file_stat.st_size;
diff --git a/tools/aconfig/aconfig_storage_write_api/src/flag_value_update.rs b/tools/aconfig/aconfig_storage_write_api/src/flag_value_update.rs
index c2375dd..4cb7939 100644
--- a/tools/aconfig/aconfig_storage_write_api/src/flag_value_update.rs
+++ b/tools/aconfig/aconfig_storage_write_api/src/flag_value_update.rs
@@ -71,7 +71,7 @@
     fn test_boolean_flag_value_update() {
         let flag_value_list = create_test_flag_value_list();
         let value_offset = flag_value_list.header.boolean_value_offset;
-        let mut content = flag_value_list.as_bytes();
+        let mut content = flag_value_list.into_bytes();
         let true_byte = u8::from(true).to_le_bytes()[0];
         let false_byte = u8::from(false).to_le_bytes()[0];
 
@@ -87,7 +87,7 @@
     #[test]
     // this test point locks down update beyond the end of boolean section
     fn test_boolean_out_of_range() {
-        let mut flag_value_list = create_test_flag_value_list().as_bytes();
+        let mut flag_value_list = create_test_flag_value_list().into_bytes();
         let error = update_boolean_flag_value(&mut flag_value_list[..], 8, true).unwrap_err();
         assert_eq!(
             format!("{:?}", error),
@@ -100,7 +100,7 @@
     fn test_higher_version_storage_file() {
         let mut value_list = create_test_flag_value_list();
         value_list.header.version = FILE_VERSION + 1;
-        let mut flag_value = value_list.as_bytes();
+        let mut flag_value = value_list.into_bytes();
         let error = update_boolean_flag_value(&mut flag_value[..], 4, true).unwrap_err();
         assert_eq!(
             format!("{:?}", error),
diff --git a/tools/aconfig/aconfig_storage_write_api/tests/flag.val b/tools/aconfig/aconfig_storage_write_api/tests/flag.val
index 75b8564..ed203d4 100644
--- a/tools/aconfig/aconfig_storage_write_api/tests/flag.val
+++ b/tools/aconfig/aconfig_storage_write_api/tests/flag.val
Binary files differ
diff --git a/tools/aconfig/aconfig_storage_write_api/tests/storage_write_api_test.cpp b/tools/aconfig/aconfig_storage_write_api/tests/storage_write_api_test.cpp
index 3a1c5de..00b737c 100644
--- a/tools/aconfig/aconfig_storage_write_api/tests/storage_write_api_test.cpp
+++ b/tools/aconfig/aconfig_storage_write_api/tests/storage_write_api_test.cpp
@@ -55,7 +55,7 @@
     auto proto = storage_files();
     auto* info = proto.add_files();
     info->set_version(0);
-    info->set_container("system");
+    info->set_container("mockup");
     info->set_package_map("some_package.map");
     info->set_flag_map("some_flag.map");
     info->set_flag_val(flag_val);
@@ -97,15 +97,16 @@
 TEST_F(AconfigStorageTest, test_non_writable_storage_file_mapping) {
   ASSERT_TRUE(chmod(flag_val.c_str(), S_IRUSR | S_IRGRP | S_IROTH) != -1);
   auto mapped_file_result = private_api::get_mapped_flag_value_file_impl(
-      storage_record_pb, "system");
+      storage_record_pb, "mockup");
   ASSERT_FALSE(mapped_file_result.ok());
-  ASSERT_EQ(mapped_file_result.error().message(), "cannot map nonwriteable file");
+  auto it = mapped_file_result.error().message().find("cannot map nonwriteable file");
+  ASSERT_TRUE(it != std::string::npos) << mapped_file_result.error().message();
 }
 
 /// Test to lock down storage flag value update api
 TEST_F(AconfigStorageTest, test_boolean_flag_value_update) {
   auto mapped_file_result = private_api::get_mapped_flag_value_file_impl(
-      storage_record_pb, "system");
+      storage_record_pb, "mockup");
   ASSERT_TRUE(mapped_file_result.ok());
   auto mapped_file = *mapped_file_result;
 
@@ -124,7 +125,7 @@
 /// Negative test to lock down the error when querying flag value out of range
 TEST_F(AconfigStorageTest, test_invalid_boolean_flag_value_update) {
   auto mapped_file_result = private_api::get_mapped_flag_value_file_impl(
-      storage_record_pb, "system");
+      storage_record_pb, "mockup");
   ASSERT_TRUE(mapped_file_result.ok());
   auto mapped_file = *mapped_file_result;
   auto update_result = api::set_boolean_flag_value(mapped_file, 8, true);
diff --git a/tools/aconfig/aconfig_storage_write_api/tests/storage_write_api_test.rs b/tools/aconfig/aconfig_storage_write_api/tests/storage_write_api_test.rs
index f6c1bbc..4bda54c 100644
--- a/tools/aconfig/aconfig_storage_write_api/tests/storage_write_api_test.rs
+++ b/tools/aconfig/aconfig_storage_write_api/tests/storage_write_api_test.rs
@@ -15,7 +15,7 @@
             r#"
 files {{
     version: 0
-    container: "system"
+    container: "mockup"
     package_map: "some_package_map"
     flag_map: "some_flag_map"
     flag_val: "{}"
@@ -59,7 +59,7 @@
         // SAFETY:
         // The safety here is ensured as only this single threaded test process will
         // write to this file
-        let mut file = unsafe { get_mapped_file(&record_pb_path, "system").unwrap() };
+        let mut file = unsafe { get_mapped_file(&record_pb_path, "mockup").unwrap() };
         for i in 0..8 {
             set_boolean_flag_value(&mut file, i, true).unwrap();
             let value = get_boolean_flag_value_at_offset(&flag_value_path, i);
diff --git a/tools/aconfig/aflags/src/aconfig_storage_source.rs b/tools/aconfig/aflags/src/aconfig_storage_source.rs
index 1d73688..a3ca221 100644
--- a/tools/aconfig/aflags/src/aconfig_storage_source.rs
+++ b/tools/aconfig/aflags/src/aconfig_storage_source.rs
@@ -27,7 +27,7 @@
             let container =
                 file_info.container.ok_or(anyhow!("storage file is missing container"))?;
 
-            for (package, name, val) in
+            for (package, name, _flag_type, val) in
                 aconfig_storage_file::list_flags(&package_map, &flag_map, &flag_val)?
             {
                 result.push(Flag {
diff --git a/tools/finalization/OWNERS b/tools/finalization/OWNERS
index 518b60d..b00b774 100644
--- a/tools/finalization/OWNERS
+++ b/tools/finalization/OWNERS
@@ -1,5 +1,7 @@
 include platform/build/soong:/OWNERS
-smoreland@google.com
-alexbuy@google.com
+amhk@google.com
+gurpreetgs@google.com
+michaelwr@google.com
 patb@google.com
+smoreland@google.com
 zyy@google.com
diff --git a/tools/protos/metadata_file.proto b/tools/protos/metadata_file.proto
index 47562c5..5c89618 100644
--- a/tools/protos/metadata_file.proto
+++ b/tools/protos/metadata_file.proto
@@ -282,7 +282,7 @@
   optional string element_id = 3;
 }
 
-// Identifier for a third-package package.
+// Identifier for a third-party package.
 // See go/tp-metadata-id.
 message Identifier {
   // The type of the identifier. Either an "ecosystem" value from
@@ -338,7 +338,19 @@
   //  - "PrebuiltByAlphabet": This type should be used for archives of primarily
   //  Google-owned source code (may contain non-Google-owned dependencies),
   //  which has been built using production Google infrastructure, and copied
-  //  into third_party.
+  //  into Android. The "value" field is the URL of the prebuilt artifact or
+  //  the relative path of the artifact to the root of a package.
+  //  Example:
+  //    identifier {
+  //      type: "PrebuiltByAlphabet",
+  //      version: "1",
+  //      value: "v1/arm84_hdpi.apk",
+  //    }
+  //    identifier {
+  //      type: "PrebuiltByAlphabet",
+  //      version: "2",
+  //      value: "v2/x86_64_xhdpi.apk",
+  //    }
   //
   //  - "LocalSource": The "value" field is the URL identifying where the local
   //  copy of the package source code can be found.
diff --git a/tools/releasetools/ota_from_target_files.py b/tools/releasetools/ota_from_target_files.py
index c0ff5d2..67438e6 100755
--- a/tools/releasetools/ota_from_target_files.py
+++ b/tools/releasetools/ota_from_target_files.py
@@ -872,6 +872,7 @@
   target_info = common.BuildInfo(OPTIONS.info_dict, OPTIONS.oem_dicts)
   if OPTIONS.disable_vabc and target_info.is_release_key:
     raise ValueError("Disabling VABC on release-key builds is not supported.")
+
   ValidateCompressionParam(target_info)
   vabc_compression_param = target_info.vabc_compression_param
 
@@ -907,7 +908,6 @@
       logger.info("Source build and target build use different compression methods {} vs {}, default to source builds parameter {}".format(
           source_info.vabc_compression_param, target_info.vabc_compression_param, source_info.vabc_compression_param))
       vabc_compression_param = source_info.vabc_compression_param
-
     # Virtual AB Cow version 3 is introduced in Android U with improved memory
     # and install time performance. All OTA's with
     # both the source build and target build with VIRTUAL_AB_COW_VERSION = 3
@@ -918,6 +918,7 @@
     elif source_info.vabc_cow_version != target_info.vabc_cow_version:
       logger.info("Source and Target have different cow VABC_COW_VERSION specified, default to minimum version")
       OPTIONS.vabc_cow_version = min(source_info.vabc_cow_version, target_info.vabc_cow_version)
+
     # Virtual AB Compression was introduced in Androd S.
     # Later, we backported VABC to Android R. But verity support was not
     # backported, so if VABC is used and we are on Android R, disable
@@ -930,6 +931,19 @@
     assert "ab_partitions" in OPTIONS.info_dict, \
         "META/ab_partitions.txt is required for ab_update."
     source_info = None
+    if not target_info.vabc_cow_version:
+        OPTIONS.vabc_cow_version = 2
+    elif target_info.vabc_cow_version >= "3" and target_info.vendor_api_level < 35:
+      logger.warning(
+            "This full OTA is configured to use VABC cow version"
+            " 3 which is supported since"
+            " Android API level 35, but device is "
+            "launched with {} . If this full OTA is"
+            " served to a device running old build, OTA might fail due to "
+            "unsupported vabc cow version. For safety, version 2 is used because "
+            "it's supported since day 1.".format(
+                target_info.vendor_api_level))
+      OPTIONS.vabc_cow_version = 2
     if OPTIONS.vabc_compression_param is None and vabc_compression_param:
       minimum_api_level_required = VABC_COMPRESSION_PARAM_SUPPORT[
           vabc_compression_param]