aconfig: update storage read api

With the update to store flag index instead of flag byte offset in
storage file. We need to update flag read api accordingly.

Bug: b/321077378
Test: atest -c
Change-Id: Iccbf939fc5b7fe0ce0f2c33f7e3aa403c268120a
diff --git a/tools/aconfig/aconfig_storage_read_api/aconfig_storage_read_api.cpp b/tools/aconfig/aconfig_storage_read_api/aconfig_storage_read_api.cpp
index ad5656a..39f1840 100644
--- a/tools/aconfig/aconfig_storage_read_api/aconfig_storage_read_api.cpp
+++ b/tools/aconfig/aconfig_storage_read_api/aconfig_storage_read_api.cpp
@@ -126,50 +126,50 @@
   }
 }
 
-/// Get package offset
-Result<PackageOffset> get_package_offset(
+/// Get package context
+Result<PackageReadContext> get_package_read_context(
     MappedStorageFile const& file,
     std::string const& package) {
   auto content = rust::Slice<const uint8_t>(
       static_cast<uint8_t*>(file.file_ptr), file.file_size);
-  auto offset_cxx = get_package_offset_cxx(content, rust::Str(package.c_str()));
-  if (offset_cxx.query_success) {
-    auto offset = PackageOffset();
-    offset.package_exists = offset_cxx.package_exists;
-    offset.package_id = offset_cxx.package_id;
-    offset.boolean_offset = offset_cxx.boolean_offset;
-    return offset;
+  auto context_cxx = get_package_read_context_cxx(content, rust::Str(package.c_str()));
+  if (context_cxx.query_success) {
+    auto context = PackageReadContext();
+    context.package_exists = context_cxx.package_exists;
+    context.package_id = context_cxx.package_id;
+    context.boolean_start_index = context_cxx.boolean_start_index;
+    return context;
   } else {
-    return Error() << offset_cxx.error_message;
+    return Error() << context_cxx.error_message;
   }
 }
 
-/// Get flag offset
-Result<FlagOffset> get_flag_offset(
+/// Get flag read context
+Result<FlagReadContext> get_flag_read_context(
     MappedStorageFile const& file,
     uint32_t package_id,
     std::string const& flag_name){
   auto content = rust::Slice<const uint8_t>(
       static_cast<uint8_t*>(file.file_ptr), file.file_size);
-  auto offset_cxx = get_flag_offset_cxx(content, package_id, rust::Str(flag_name.c_str()));
-  if (offset_cxx.query_success) {
-    auto offset = FlagOffset();
-    offset.flag_exists = offset_cxx.flag_exists;
-    offset.flag_type = static_cast<StoredFlagType>(offset_cxx.flag_type);
-    offset.flag_id = offset_cxx.flag_id;
-    return offset;
+  auto context_cxx = get_flag_read_context_cxx(content, package_id, rust::Str(flag_name.c_str()));
+  if (context_cxx.query_success) {
+    auto context = FlagReadContext();
+    context.flag_exists = context_cxx.flag_exists;
+    context.flag_type = static_cast<StoredFlagType>(context_cxx.flag_type);
+    context.flag_index = context_cxx.flag_index;
+    return context;
   } else {
-   return Error() << offset_cxx.error_message;
+   return Error() << context_cxx.error_message;
   }
 }
 
 /// Get boolean flag value
 Result<bool> get_boolean_flag_value(
     MappedStorageFile const& file,
-    uint32_t offset) {
+    uint32_t index) {
   auto content = rust::Slice<const uint8_t>(
       static_cast<uint8_t*>(file.file_ptr), file.file_size);
-  auto value_cxx = get_boolean_flag_value_cxx(content, offset);
+  auto value_cxx = get_boolean_flag_value_cxx(content, index);
   if (value_cxx.query_success) {
     return value_cxx.flag_value;
   } else {
@@ -180,10 +180,10 @@
 /// Get boolean flag attribute
 Result<uint8_t> get_boolean_flag_attribute(
     MappedStorageFile const& file,
-    uint32_t offset) {
+    uint32_t index) {
   auto content = rust::Slice<const uint8_t>(
       static_cast<uint8_t*>(file.file_ptr), file.file_size);
-  auto info_cxx = get_boolean_flag_attribute_cxx(content, offset);
+  auto info_cxx = get_boolean_flag_attribute_cxx(content, index);
   if (info_cxx.query_success) {
     return info_cxx.flag_attribute;
   } else {
diff --git a/tools/aconfig/aconfig_storage_read_api/include/aconfig_storage/aconfig_storage_read_api.hpp b/tools/aconfig/aconfig_storage_read_api/include/aconfig_storage/aconfig_storage_read_api.hpp
index b2a6e41..521ff15 100644
--- a/tools/aconfig/aconfig_storage_read_api/include/aconfig_storage/aconfig_storage_read_api.hpp
+++ b/tools/aconfig/aconfig_storage_read_api/include/aconfig_storage/aconfig_storage_read_api.hpp
@@ -20,11 +20,11 @@
   size_t file_size;
 };
 
-/// Package offset query result
-struct PackageOffset {
+/// Package read context query result
+struct PackageReadContext {
   bool package_exists;
   uint32_t package_id;
-  uint32_t boolean_offset;
+  uint32_t boolean_start_index;
 };
 
 /// Flag type enum, to be consistent with the one defined in aconfig_storage_file/src/lib.rs
@@ -34,11 +34,11 @@
   FixedReadOnlyBoolean = 2,
 };
 
-/// Flag offset query result
-struct FlagOffset {
+/// Flag read context query result
+struct FlagReadContext {
   bool flag_exists;
   StoredFlagType flag_type;
-  uint16_t flag_id;
+  uint16_t flag_index;
 };
 
 /// DO NOT USE APIS IN THE FOLLOWING NAMESPACE DIRECTLY
@@ -65,31 +65,31 @@
 android::base::Result<uint32_t> get_storage_file_version(
     std::string const& file_path);
 
-/// Get package offset
+/// Get package read context
 /// \input file: mapped storage file
 /// \input package: the flag package name
-/// \returns a package offset
-android::base::Result<PackageOffset> get_package_offset(
+/// \returns a package read context
+android::base::Result<PackageReadContext> get_package_read_context(
     MappedStorageFile const& file,
     std::string const& package);
 
-/// Get flag offset
+/// Get flag read context
 /// \input file: mapped storage file
 /// \input package_id: the flag package id obtained from package offset query
 /// \input flag_name: flag name
-/// \returns the flag offset
-android::base::Result<FlagOffset> get_flag_offset(
+/// \returns the flag read context
+android::base::Result<FlagReadContext> get_flag_read_context(
     MappedStorageFile const& file,
     uint32_t package_id,
     std::string const& flag_name);
 
 /// Get boolean flag value
 /// \input file: mapped storage file
-/// \input offset: the boolean flag value offset in the file
+/// \input index: the boolean flag index in the file
 /// \returns the boolean flag value
 android::base::Result<bool> get_boolean_flag_value(
     MappedStorageFile const& file,
-    uint32_t offset);
+    uint32_t index);
 
 /// Flag info enum, to be consistent with the one defined in aconfig_storage_file/src/lib.rs
 enum FlagInfoBit {
@@ -100,9 +100,9 @@
 
 /// Get boolean flag attribute
 /// \input file: mapped storage file
-/// \input offset: the boolean flag info offset in the file
+/// \input index: the boolean flag index in the file
 /// \returns the boolean flag attribute
 android::base::Result<uint8_t> get_boolean_flag_attribute(
     MappedStorageFile const& file,
-    uint32_t offset);
+    uint32_t index);
 } // namespace aconfig_storage
diff --git a/tools/aconfig/aconfig_storage_read_api/src/flag_info_query.rs b/tools/aconfig/aconfig_storage_read_api/src/flag_info_query.rs
index 2f8c536..807da97 100644
--- a/tools/aconfig/aconfig_storage_read_api/src/flag_info_query.rs
+++ b/tools/aconfig/aconfig_storage_read_api/src/flag_info_query.rs
@@ -21,10 +21,7 @@
 use anyhow::anyhow;
 
 /// Get flag attribute bitfield
-pub fn find_boolean_flag_attribute(
-    buf: &[u8],
-    flag_offset: u32,
-) -> Result<u8, AconfigStorageError> {
+pub fn find_boolean_flag_attribute(buf: &[u8], flag_index: u32) -> Result<u8, AconfigStorageError> {
     let interpreted_header = FlagInfoHeader::from_bytes(buf)?;
     if interpreted_header.version > crate::FILE_VERSION {
         return Err(AconfigStorageError::HigherStorageFileVersion(anyhow!(
@@ -34,8 +31,8 @@
         )));
     }
 
-    let mut head = (interpreted_header.boolean_flag_offset + flag_offset) as usize;
-
+    // Find the byte offset to the flag info, each flag info now takes one byte
+    let mut head = (interpreted_header.boolean_flag_offset + flag_index) as usize;
     if head >= interpreted_header.file_size as usize {
         return Err(AconfigStorageError::InvalidStorageFileOffset(anyhow!(
             "Flag info offset goes beyond the end of the file."
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 ad8e394..55fdcb7 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
@@ -24,17 +24,17 @@
 
 /// Flag table query return
 #[derive(PartialEq, Debug)]
-pub struct FlagOffset {
+pub struct FlagReadContext {
     pub flag_type: StoredFlagType,
-    pub flag_id: u16,
+    pub flag_index: u16,
 }
 
-/// Query flag within package offset
-pub fn find_flag_offset(
+/// Query flag read context: flag type and within package flag index
+pub fn find_flag_read_context(
     buf: &[u8],
     package_id: u32,
     flag: &str,
-) -> Result<Option<FlagOffset>, AconfigStorageError> {
+) -> Result<Option<FlagReadContext>, AconfigStorageError> {
     let interpreted_header = FlagTableHeader::from_bytes(buf)?;
     if interpreted_header.version > crate::FILE_VERSION {
         return Err(AconfigStorageError::HigherStorageFileVersion(anyhow!(
@@ -58,9 +58,9 @@
     loop {
         let interpreted_node = FlagTableNode::from_bytes(&buf[flag_node_offset..])?;
         if interpreted_node.package_id == package_id && interpreted_node.flag_name == flag {
-            return Ok(Some(FlagOffset {
+            return Ok(Some(FlagReadContext {
                 flag_type: interpreted_node.flag_type,
-                flag_id: interpreted_node.flag_id,
+                flag_index: interpreted_node.flag_index,
             }));
         }
         match interpreted_node.next_offset {
@@ -89,11 +89,11 @@
             (2, "enabled_fixed_ro", StoredFlagType::FixedReadOnlyBoolean, 0u16),
             (0, "disabled_rw", StoredFlagType::ReadWriteBoolean, 0u16),
         ];
-        for (package_id, flag_name, flag_type, flag_id) in baseline.into_iter() {
-            let flag_offset =
-                find_flag_offset(&flag_table[..], package_id, flag_name).unwrap().unwrap();
-            assert_eq!(flag_offset.flag_type, flag_type);
-            assert_eq!(flag_offset.flag_id, flag_id);
+        for (package_id, flag_name, flag_type, flag_index) in baseline.into_iter() {
+            let flag_context =
+                find_flag_read_context(&flag_table[..], package_id, flag_name).unwrap().unwrap();
+            assert_eq!(flag_context.flag_type, flag_type);
+            assert_eq!(flag_context.flag_index, flag_index);
         }
     }
 
@@ -101,10 +101,10 @@
     // 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().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();
-        assert_eq!(flag_offset, None);
+        let flag_context = find_flag_read_context(&flag_table[..], 1, "disabled_fixed_ro").unwrap();
+        assert_eq!(flag_context, None);
+        let flag_context = find_flag_read_context(&flag_table[..], 2, "disabled_rw").unwrap();
+        assert_eq!(flag_context, None);
     }
 
     #[test]
@@ -113,7 +113,7 @@
         let mut table = create_test_flag_table();
         table.header.version = crate::FILE_VERSION + 1;
         let flag_table = table.into_bytes();
-        let error = find_flag_offset(&flag_table[..], 0, "enabled_ro").unwrap_err();
+        let error = find_flag_read_context(&flag_table[..], 0, "enabled_ro").unwrap_err();
         assert_eq!(
             format!("{:?}", error),
             format!(
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 7324f43..9d32a16 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
@@ -21,7 +21,7 @@
 use anyhow::anyhow;
 
 /// Query flag value
-pub fn find_boolean_flag_value(buf: &[u8], flag_offset: u32) -> Result<bool, AconfigStorageError> {
+pub fn find_boolean_flag_value(buf: &[u8], flag_index: u32) -> Result<bool, AconfigStorageError> {
     let interpreted_header = FlagValueHeader::from_bytes(buf)?;
     if interpreted_header.version > crate::FILE_VERSION {
         return Err(AconfigStorageError::HigherStorageFileVersion(anyhow!(
@@ -31,10 +31,8 @@
         )));
     }
 
-    let mut head = (interpreted_header.boolean_value_offset + flag_offset) as usize;
-
-    // TODO: right now, there is only boolean flags, with more flag value types added
-    // later, the end of boolean flag value section should be updated (b/322826265).
+    // Find byte offset to the flag value, each boolean flag cost one byte to store
+    let mut head = (interpreted_header.boolean_value_offset + flag_index) as usize;
     if head >= interpreted_header.file_size as usize {
         return Err(AconfigStorageError::InvalidStorageFileOffset(anyhow!(
             "Flag value offset goes beyond the end of the file."
diff --git a/tools/aconfig/aconfig_storage_read_api/src/lib.rs b/tools/aconfig/aconfig_storage_read_api/src/lib.rs
index 960446d..aa0145f 100644
--- a/tools/aconfig/aconfig_storage_read_api/src/lib.rs
+++ b/tools/aconfig/aconfig_storage_read_api/src/lib.rs
@@ -17,14 +17,16 @@
 //! `aconfig_storage_read_api` is a crate that defines read apis to read flags from storage
 //! files. It provides four apis to interface with storage files:
 //!
-//! 1, function to get package flag value start offset
-//! pub fn get_package_offset(container: &str, package: &str) -> `Result<Option<PackageOffset>>>`
+//! 1, function to get package read context
+//! pub fn get_packager_read_context(container: &str, package: &str)
+//! -> `Result<Option<PackageReadContext>>>`
 //!
-//! 2, function to get flag offset within a specific package
-//! pub fn get_flag_offset(container: &str, package_id: u32, flag: &str) -> `Result<Option<u16>>>`
+//! 2, function to get flag read context
+//! pub fn get_flag_read_context(container: &str, package_id: u32, flag: &str)
+//! -> `Result<Option<FlagReadContext>>>`
 //!
-//! 3, function to get the actual flag value given the global offset (combined package and
-//! flag offset).
+//! 3, function to get the actual flag value given the global index (combined package and
+//! flag index).
 //! pub fn get_boolean_flag_value(container: &str, offset: u32) -> `Result<bool>`
 //!
 //! 4, function to get storage file version without mmapping the file.
@@ -44,14 +46,14 @@
 mod test_utils;
 
 pub use aconfig_storage_file::{AconfigStorageError, StorageFileType};
-pub use flag_table_query::FlagOffset;
-pub use package_table_query::PackageOffset;
+pub use flag_table_query::FlagReadContext;
+pub use package_table_query::PackageReadContext;
 
 use aconfig_storage_file::{read_u32_from_bytes, FILE_VERSION};
 use flag_info_query::find_boolean_flag_attribute;
-use flag_table_query::find_flag_offset;
+use flag_table_query::find_flag_read_context;
 use flag_value_query::find_boolean_flag_value;
-use package_table_query::find_package_offset;
+use package_table_query::find_package_read_context;
 
 use anyhow::anyhow;
 use memmap2::Mmap;
@@ -79,50 +81,50 @@
     unsafe { crate::mapped_file::get_mapped_file(STORAGE_LOCATION_FILE, container, file_type) }
 }
 
-/// Get package start offset for flags.
+/// Get package read context for a specific package.
 ///
 /// \input file: mapped package file
 /// \input package: package name
 ///
 /// \return
-/// If a package is found, it returns Ok(Some(PackageOffset))
+/// If a package is found, it returns Ok(Some(PackageReadContext))
 /// If a package is not found, it returns Ok(None)
 /// If errors out, it returns an Err(errmsg)
-pub fn get_package_offset(
+pub fn get_package_read_context(
     file: &Mmap,
     package: &str,
-) -> Result<Option<PackageOffset>, AconfigStorageError> {
-    find_package_offset(file, package)
+) -> Result<Option<PackageReadContext>, AconfigStorageError> {
+    find_package_read_context(file, package)
 }
 
-/// Get flag offset within a package given.
+/// Get flag read context for a specific flag.
 ///
 /// \input file: mapped flag file
 /// \input package_id: package id obtained from package mapping file
 /// \input flag: flag name
 ///
 /// \return
-/// If a flag is found, it returns Ok(Some(u16))
+/// If a flag is found, it returns Ok(Some(FlagReadContext))
 /// If a flag is not found, it returns Ok(None)
 /// If errors out, it returns an Err(errmsg)
-pub fn get_flag_offset(
+pub fn get_flag_read_context(
     file: &Mmap,
     package_id: u32,
     flag: &str,
-) -> Result<Option<FlagOffset>, AconfigStorageError> {
-    find_flag_offset(file, package_id, flag)
+) -> Result<Option<FlagReadContext>, AconfigStorageError> {
+    find_flag_read_context(file, package_id, flag)
 }
 
 /// Get the boolean flag value.
 ///
 /// \input file: mapped flag file
-/// \input offset: flag value offset
+/// \input index: boolean flag offset
 ///
 /// \return
 /// If the provide offset is valid, it returns the boolean flag value, otherwise it
 /// returns the error message.
-pub fn get_boolean_flag_value(file: &Mmap, offset: u32) -> Result<bool, AconfigStorageError> {
-    find_boolean_flag_value(file, offset)
+pub fn get_boolean_flag_value(file: &Mmap, index: u32) -> Result<bool, AconfigStorageError> {
+    find_boolean_flag_value(file, index)
 }
 
 /// Get storage file version number
@@ -150,13 +152,13 @@
 /// Get the boolean flag attribute.
 ///
 /// \input file: mapped flag info file
-/// \input offset: boolean flag offset
+/// \input index: boolean flag index
 ///
 /// \return
 /// If the provide offset is valid, it returns the boolean flag attribute bitfiled, otherwise it
 /// returns the error message.
-pub fn get_boolean_flag_attribute(file: &Mmap, offset: u32) -> Result<u8, AconfigStorageError> {
-    find_boolean_flag_attribute(file, offset)
+pub fn get_boolean_flag_attribute(file: &Mmap, index: u32) -> Result<u8, AconfigStorageError> {
+    find_boolean_flag_attribute(file, index)
 }
 
 // *************************************** //
@@ -174,21 +176,21 @@
     }
 
     // Package table query return for cc interlop
-    pub struct PackageOffsetQueryCXX {
+    pub struct PackageReadContextQueryCXX {
         pub query_success: bool,
         pub error_message: String,
         pub package_exists: bool,
         pub package_id: u32,
-        pub boolean_offset: u32,
+        pub boolean_start_index: u32,
     }
 
     // Flag table query return for cc interlop
-    pub struct FlagOffsetQueryCXX {
+    pub struct FlagReadContextQueryCXX {
         pub query_success: bool,
         pub error_message: String,
         pub flag_exists: bool,
         pub flag_type: u16,
-        pub flag_id: u16,
+        pub flag_index: u16,
     }
 
     // Flag value query return for cc interlop
@@ -209,9 +211,16 @@
     extern "Rust" {
         pub fn get_storage_file_version_cxx(file_path: &str) -> VersionNumberQueryCXX;
 
-        pub fn get_package_offset_cxx(file: &[u8], package: &str) -> PackageOffsetQueryCXX;
+        pub fn get_package_read_context_cxx(
+            file: &[u8],
+            package: &str,
+        ) -> PackageReadContextQueryCXX;
 
-        pub fn get_flag_offset_cxx(file: &[u8], package_id: u32, flag: &str) -> FlagOffsetQueryCXX;
+        pub fn get_flag_read_context_cxx(
+            file: &[u8],
+            package_id: u32,
+            flag: &str,
+        ) -> FlagReadContextQueryCXX;
 
         pub fn get_boolean_flag_value_cxx(file: &[u8], offset: u32) -> BooleanFlagValueQueryCXX;
 
@@ -223,8 +232,10 @@
 }
 
 /// Implement the package offset interlop return type, create from actual package offset api return type
-impl ffi::PackageOffsetQueryCXX {
-    pub(crate) fn new(offset_result: Result<Option<PackageOffset>, AconfigStorageError>) -> Self {
+impl ffi::PackageReadContextQueryCXX {
+    pub(crate) fn new(
+        offset_result: Result<Option<PackageReadContext>, AconfigStorageError>,
+    ) -> Self {
         match offset_result {
             Ok(offset_opt) => match offset_opt {
                 Some(offset) => Self {
@@ -232,14 +243,14 @@
                     error_message: String::from(""),
                     package_exists: true,
                     package_id: offset.package_id,
-                    boolean_offset: offset.boolean_offset,
+                    boolean_start_index: offset.boolean_start_index,
                 },
                 None => Self {
                     query_success: true,
                     error_message: String::from(""),
                     package_exists: false,
                     package_id: 0,
-                    boolean_offset: 0,
+                    boolean_start_index: 0,
                 },
             },
             Err(errmsg) => Self {
@@ -247,15 +258,15 @@
                 error_message: format!("{:?}", errmsg),
                 package_exists: false,
                 package_id: 0,
-                boolean_offset: 0,
+                boolean_start_index: 0,
             },
         }
     }
 }
 
 /// Implement the flag offset interlop return type, create from actual flag offset api return type
-impl ffi::FlagOffsetQueryCXX {
-    pub(crate) fn new(offset_result: Result<Option<FlagOffset>, AconfigStorageError>) -> Self {
+impl ffi::FlagReadContextQueryCXX {
+    pub(crate) fn new(offset_result: Result<Option<FlagReadContext>, AconfigStorageError>) -> Self {
         match offset_result {
             Ok(offset_opt) => match offset_opt {
                 Some(offset) => Self {
@@ -263,14 +274,14 @@
                     error_message: String::from(""),
                     flag_exists: true,
                     flag_type: offset.flag_type as u16,
-                    flag_id: offset.flag_id,
+                    flag_index: offset.flag_index,
                 },
                 None => Self {
                     query_success: true,
                     error_message: String::from(""),
                     flag_exists: false,
                     flag_type: 0u16,
-                    flag_id: 0u16,
+                    flag_index: 0u16,
                 },
             },
             Err(errmsg) => Self {
@@ -278,7 +289,7 @@
                 error_message: format!("{:?}", errmsg),
                 flag_exists: false,
                 flag_type: 0u16,
-                flag_id: 0u16,
+                flag_index: 0u16,
             },
         }
     }
@@ -335,14 +346,18 @@
     }
 }
 
-/// Get package start offset cc interlop
-pub fn get_package_offset_cxx(file: &[u8], package: &str) -> ffi::PackageOffsetQueryCXX {
-    ffi::PackageOffsetQueryCXX::new(find_package_offset(file, package))
+/// Get package read context cc interlop
+pub fn get_package_read_context_cxx(file: &[u8], package: &str) -> ffi::PackageReadContextQueryCXX {
+    ffi::PackageReadContextQueryCXX::new(find_package_read_context(file, package))
 }
 
-/// Get flag start offset cc interlop
-pub fn get_flag_offset_cxx(file: &[u8], package_id: u32, flag: &str) -> ffi::FlagOffsetQueryCXX {
-    ffi::FlagOffsetQueryCXX::new(find_flag_offset(file, package_id, flag))
+/// Get flag read context cc interlop
+pub fn get_flag_read_context_cxx(
+    file: &[u8],
+    package_id: u32,
+    flag: &str,
+) -> ffi::FlagReadContextQueryCXX {
+    ffi::FlagReadContextQueryCXX::new(find_flag_read_context(file, package_id, flag))
 }
 
 /// Get boolean flag value cc interlop
@@ -400,39 +415,39 @@
     }
 
     #[test]
-    // this test point locks down flag package offset query
-    fn test_package_offset_query() {
+    // this test point locks down flag package read context query
+    fn test_package_context_query() {
         let [_package_map, _flag_map, _flag_val, _flag_info, pb_file] = create_test_storage_files();
         let pb_file_path = pb_file.path().display().to_string();
         let package_mapped_file = unsafe {
             get_mapped_file(&pb_file_path, "mockup", StorageFileType::PackageMap).unwrap()
         };
 
-        let package_offset =
-            get_package_offset(&package_mapped_file, "com.android.aconfig.storage.test_1")
+        let package_context =
+            get_package_read_context(&package_mapped_file, "com.android.aconfig.storage.test_1")
                 .unwrap()
                 .unwrap();
-        let expected_package_offset = PackageOffset { package_id: 0, boolean_offset: 0 };
-        assert_eq!(package_offset, expected_package_offset);
+        let expected_package_context = PackageReadContext { package_id: 0, boolean_start_index: 0 };
+        assert_eq!(package_context, expected_package_context);
 
-        let package_offset =
-            get_package_offset(&package_mapped_file, "com.android.aconfig.storage.test_2")
+        let package_context =
+            get_package_read_context(&package_mapped_file, "com.android.aconfig.storage.test_2")
                 .unwrap()
                 .unwrap();
-        let expected_package_offset = PackageOffset { package_id: 1, boolean_offset: 3 };
-        assert_eq!(package_offset, expected_package_offset);
+        let expected_package_context = PackageReadContext { package_id: 1, boolean_start_index: 3 };
+        assert_eq!(package_context, expected_package_context);
 
-        let package_offset =
-            get_package_offset(&package_mapped_file, "com.android.aconfig.storage.test_4")
+        let package_context =
+            get_package_read_context(&package_mapped_file, "com.android.aconfig.storage.test_4")
                 .unwrap()
                 .unwrap();
-        let expected_package_offset = PackageOffset { package_id: 2, boolean_offset: 6 };
-        assert_eq!(package_offset, expected_package_offset);
+        let expected_package_context = PackageReadContext { package_id: 2, boolean_start_index: 6 };
+        assert_eq!(package_context, expected_package_context);
     }
 
     #[test]
-    // this test point locks down flag offset query
-    fn test_flag_offset_query() {
+    // this test point locks down flag read context query
+    fn test_flag_context_query() {
         let [_package_map, _flag_map, _flag_val, _flag_info, pb_file] = create_test_storage_files();
         let pb_file_path = pb_file.path().display().to_string();
         let flag_mapped_file =
@@ -448,11 +463,11 @@
             (2, "enabled_fixed_ro", StoredFlagType::FixedReadOnlyBoolean, 0u16),
             (0, "disabled_rw", StoredFlagType::ReadWriteBoolean, 0u16),
         ];
-        for (package_id, flag_name, flag_type, flag_id) in baseline.into_iter() {
-            let flag_offset =
-                get_flag_offset(&flag_mapped_file, package_id, flag_name).unwrap().unwrap();
-            assert_eq!(flag_offset.flag_type, flag_type);
-            assert_eq!(flag_offset.flag_id, flag_id);
+        for (package_id, flag_name, flag_type, flag_index) in baseline.into_iter() {
+            let flag_context =
+                get_flag_read_context(&flag_mapped_file, package_id, flag_name).unwrap().unwrap();
+            assert_eq!(flag_context.flag_type, flag_type);
+            assert_eq!(flag_context.flag_index, flag_index);
         }
     }
 
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 d83844e..2cb854b 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
@@ -24,16 +24,16 @@
 
 /// Package table query return
 #[derive(PartialEq, Debug)]
-pub struct PackageOffset {
+pub struct PackageReadContext {
     pub package_id: u32,
-    pub boolean_offset: u32,
+    pub boolean_start_index: u32,
 }
 
-/// Query package id and start offset
-pub fn find_package_offset(
+/// Query package read context: package id and start index
+pub fn find_package_read_context(
     buf: &[u8],
     package: &str,
-) -> Result<Option<PackageOffset>, AconfigStorageError> {
+) -> Result<Option<PackageReadContext>, AconfigStorageError> {
     let interpreted_header = PackageTableHeader::from_bytes(buf)?;
     if interpreted_header.version > FILE_VERSION {
         return Err(AconfigStorageError::HigherStorageFileVersion(anyhow!(
@@ -57,9 +57,9 @@
     loop {
         let interpreted_node = PackageTableNode::from_bytes(&buf[package_node_offset..])?;
         if interpreted_node.package_name == package {
-            return Ok(Some(PackageOffset {
+            return Ok(Some(PackageReadContext {
                 package_id: interpreted_node.package_id,
-                boolean_offset: interpreted_node.boolean_offset,
+                boolean_start_index: interpreted_node.boolean_start_index,
             }));
         }
         match interpreted_node.next_offset {
@@ -78,24 +78,24 @@
     // this test point locks down table query
     fn test_package_query() {
         let package_table = create_test_package_table().into_bytes();
-        let package_offset =
-            find_package_offset(&package_table[..], "com.android.aconfig.storage.test_1")
+        let package_context =
+            find_package_read_context(&package_table[..], "com.android.aconfig.storage.test_1")
                 .unwrap()
                 .unwrap();
-        let expected_package_offset = PackageOffset { package_id: 0, boolean_offset: 0 };
-        assert_eq!(package_offset, expected_package_offset);
-        let package_offset =
-            find_package_offset(&package_table[..], "com.android.aconfig.storage.test_2")
+        let expected_package_context = PackageReadContext { package_id: 0, boolean_start_index: 0 };
+        assert_eq!(package_context, expected_package_context);
+        let package_context =
+            find_package_read_context(&package_table[..], "com.android.aconfig.storage.test_2")
                 .unwrap()
                 .unwrap();
-        let expected_package_offset = PackageOffset { package_id: 1, boolean_offset: 3 };
-        assert_eq!(package_offset, expected_package_offset);
-        let package_offset =
-            find_package_offset(&package_table[..], "com.android.aconfig.storage.test_4")
+        let expected_package_context = PackageReadContext { package_id: 1, boolean_start_index: 3 };
+        assert_eq!(package_context, expected_package_context);
+        let package_context =
+            find_package_read_context(&package_table[..], "com.android.aconfig.storage.test_4")
                 .unwrap()
                 .unwrap();
-        let expected_package_offset = PackageOffset { package_id: 2, boolean_offset: 6 };
-        assert_eq!(package_offset, expected_package_offset);
+        let expected_package_context = PackageReadContext { package_id: 2, boolean_start_index: 6 };
+        assert_eq!(package_context, expected_package_context);
     }
 
     #[test]
@@ -103,13 +103,15 @@
     fn test_not_existed_package_query() {
         // this will land at an empty bucket
         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);
+        let package_context =
+            find_package_read_context(&package_table[..], "com.android.aconfig.storage.test_3")
+                .unwrap();
+        assert_eq!(package_context, None);
         // this will land at the end of a linked list
-        let package_offset =
-            find_package_offset(&package_table[..], "com.android.aconfig.storage.test_5").unwrap();
-        assert_eq!(package_offset, None);
+        let package_context =
+            find_package_read_context(&package_table[..], "com.android.aconfig.storage.test_5")
+                .unwrap();
+        assert_eq!(package_context, None);
     }
 
     #[test]
@@ -118,8 +120,9 @@
         let mut table = create_test_package_table();
         table.header.version = crate::FILE_VERSION + 1;
         let package_table = table.into_bytes();
-        let error = find_package_offset(&package_table[..], "com.android.aconfig.storage.test_1")
-            .unwrap_err();
+        let error =
+            find_package_read_context(&package_table[..], "com.android.aconfig.storage.test_1")
+                .unwrap_err();
         assert_eq!(
             format!("{:?}", error),
             format!(
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 3fd0173..8ed3756 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
@@ -104,6 +104,9 @@
   version = api::get_storage_file_version(flag_val);
   ASSERT_TRUE(version.ok());
   ASSERT_EQ(*version, 1);
+  version = api::get_storage_file_version(flag_info);
+  ASSERT_TRUE(version.ok());
+  ASSERT_EQ(*version, 1);
 }
 
 /// Negative test to lock down the error when mapping none exist storage files
@@ -115,48 +118,48 @@
             "Unable to find storage files for container vendor");
 }
 
-/// Test to lock down storage package offset query api
-TEST_F(AconfigStorageTest, test_package_offset_query) {
+/// Test to lock down storage package context query api
+TEST_F(AconfigStorageTest, test_package_context_query) {
   auto mapped_file = private_api::get_mapped_file_impl(
       storage_record_pb, "mockup", api::StorageFileType::package_map);
   ASSERT_TRUE(mapped_file.ok());
 
-  auto offset = api::get_package_offset(
+  auto context = api::get_package_read_context(
       *mapped_file, "com.android.aconfig.storage.test_1");
-  ASSERT_TRUE(offset.ok());
-  ASSERT_TRUE(offset->package_exists);
-  ASSERT_EQ(offset->package_id, 0);
-  ASSERT_EQ(offset->boolean_offset, 0);
+  ASSERT_TRUE(context.ok());
+  ASSERT_TRUE(context->package_exists);
+  ASSERT_EQ(context->package_id, 0);
+  ASSERT_EQ(context->boolean_start_index, 0);
 
-  offset = api::get_package_offset(
+  context = api::get_package_read_context(
       *mapped_file, "com.android.aconfig.storage.test_2");
-  ASSERT_TRUE(offset.ok());
-  ASSERT_TRUE(offset->package_exists);
-  ASSERT_EQ(offset->package_id, 1);
-  ASSERT_EQ(offset->boolean_offset, 3);
+  ASSERT_TRUE(context.ok());
+  ASSERT_TRUE(context->package_exists);
+  ASSERT_EQ(context->package_id, 1);
+  ASSERT_EQ(context->boolean_start_index, 3);
 
-  offset = api::get_package_offset(
+  context = api::get_package_read_context(
       *mapped_file, "com.android.aconfig.storage.test_4");
-  ASSERT_TRUE(offset.ok());
-  ASSERT_TRUE(offset->package_exists);
-  ASSERT_EQ(offset->package_id, 2);
-  ASSERT_EQ(offset->boolean_offset, 6);
+  ASSERT_TRUE(context.ok());
+  ASSERT_TRUE(context->package_exists);
+  ASSERT_EQ(context->package_id, 2);
+  ASSERT_EQ(context->boolean_start_index, 6);
 }
 
 /// Test to lock down when querying none exist package
-TEST_F(AconfigStorageTest, test_none_existent_package_offset_query) {
+TEST_F(AconfigStorageTest, test_none_existent_package_context_query) {
   auto mapped_file = private_api::get_mapped_file_impl(
       storage_record_pb, "mockup", api::StorageFileType::package_map);
   ASSERT_TRUE(mapped_file.ok());
 
-  auto offset = api::get_package_offset(
+  auto context = api::get_package_read_context(
       *mapped_file, "com.android.aconfig.storage.test_3");
-  ASSERT_TRUE(offset.ok());
-  ASSERT_FALSE(offset->package_exists);
+  ASSERT_TRUE(context.ok());
+  ASSERT_FALSE(context->package_exists);
 }
 
-/// Test to lock down storage flag offset query api
-TEST_F(AconfigStorageTest, test_flag_offset_query) {
+/// Test to lock down storage flag context query api
+TEST_F(AconfigStorageTest, test_flag_context_query) {
   auto mapped_file = private_api::get_mapped_file_impl(
       storage_record_pb, "mockup", api::StorageFileType::flag_map);
   ASSERT_TRUE(mapped_file.ok());
@@ -171,28 +174,28 @@
     {2, "enabled_fixed_ro", api::StoredFlagType::FixedReadOnlyBoolean, 0},
     {0, "disabled_rw", api::StoredFlagType::ReadWriteBoolean, 0},
   };
-  for (auto const&[package_id, flag_name, flag_type, flag_id] : baseline) {
-    auto offset = api::get_flag_offset(*mapped_file, package_id, flag_name);
-    ASSERT_TRUE(offset.ok());
-    ASSERT_TRUE(offset->flag_exists);
-    ASSERT_EQ(offset->flag_type, flag_type);
-    ASSERT_EQ(offset->flag_id, flag_id);
+  for (auto const&[package_id, flag_name, flag_type, flag_index] : baseline) {
+    auto context = api::get_flag_read_context(*mapped_file, package_id, flag_name);
+    ASSERT_TRUE(context.ok());
+    ASSERT_TRUE(context->flag_exists);
+    ASSERT_EQ(context->flag_type, flag_type);
+    ASSERT_EQ(context->flag_index, flag_index);
   }
 }
 
 /// Test to lock down when querying none exist flag
-TEST_F(AconfigStorageTest, test_none_existent_flag_offset_query) {
+TEST_F(AconfigStorageTest, test_none_existent_flag_context_query) {
   auto mapped_file = private_api::get_mapped_file_impl(
       storage_record_pb, "mockup", api::StorageFileType::flag_map);
   ASSERT_TRUE(mapped_file.ok());
 
-  auto offset = api::get_flag_offset(*mapped_file, 0, "none_exist");
-  ASSERT_TRUE(offset.ok());
-  ASSERT_FALSE(offset->flag_exists);
+  auto context = api::get_flag_read_context(*mapped_file, 0, "none_exist");
+  ASSERT_TRUE(context.ok());
+  ASSERT_FALSE(context->flag_exists);
 
-  offset = api::get_flag_offset(*mapped_file, 3, "enabled_ro");
-  ASSERT_TRUE(offset.ok());
-  ASSERT_FALSE(offset->flag_exists);
+  context = api::get_flag_read_context(*mapped_file, 3, "enabled_ro");
+  ASSERT_TRUE(context.ok());
+  ASSERT_FALSE(context->flag_exists);
 }
 
 /// Test to lock down storage flag value query api
@@ -203,10 +206,10 @@
 
   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);
+  for (int index = 0; index < 8; ++index) {
+    auto value = api::get_boolean_flag_value(*mapped_file, index);
     ASSERT_TRUE(value.ok());
-    ASSERT_EQ(*value, expected_value[offset]);
+    ASSERT_EQ(*value, expected_value[index]);
   }
 }
 
@@ -230,12 +233,12 @@
 
   auto expected_value = std::vector<bool>{
     true, false, true, false, false, false, false, false};
-  for (int offset = 0; offset < 8; ++offset) {
-    auto attribute = api::get_boolean_flag_attribute(*mapped_file, offset);
+  for (int index = 0; index < 8; ++index) {
+    auto attribute = api::get_boolean_flag_attribute(*mapped_file, index);
     ASSERT_TRUE(attribute.ok());
     ASSERT_EQ(*attribute & static_cast<uint8_t>(api::FlagInfoBit::IsSticky), 0);
     ASSERT_EQ((*attribute & static_cast<uint8_t>(api::FlagInfoBit::IsReadWrite)) != 0,
-              expected_value[offset]);
+              expected_value[index]);
     ASSERT_EQ(*attribute & static_cast<uint8_t>(api::FlagInfoBit::HasOverride), 0);
   }
 }
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 21caead..bddb396 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
@@ -3,8 +3,9 @@
     use aconfig_storage_file::protos::storage_record_pb::write_proto_to_temp_file;
     use aconfig_storage_file::{FlagInfoBit, StorageFileType, StoredFlagType};
     use aconfig_storage_read_api::{
-        get_boolean_flag_attribute, get_boolean_flag_value, get_flag_offset, get_package_offset,
-        get_storage_file_version, mapped_file::get_mapped_file, PackageOffset,
+        get_boolean_flag_attribute, get_boolean_flag_value, get_flag_read_context,
+        get_package_read_context, get_storage_file_version, mapped_file::get_mapped_file,
+        PackageReadContext,
     };
     use std::fs;
     use tempfile::NamedTempFile;
@@ -58,7 +59,7 @@
     }
 
     #[test]
-    fn test_package_offset_query() {
+    fn test_package_context_query() {
         let [_package_map, _flag_map, _flag_val, _flag_info, pb_file] = create_test_storage_files();
         let pb_file_path = pb_file.path().display().to_string();
         // SAFETY:
@@ -67,30 +68,30 @@
             get_mapped_file(&pb_file_path, "mockup", StorageFileType::PackageMap).unwrap()
         };
 
-        let package_offset =
-            get_package_offset(&package_mapped_file, "com.android.aconfig.storage.test_1")
+        let package_context =
+            get_package_read_context(&package_mapped_file, "com.android.aconfig.storage.test_1")
                 .unwrap()
                 .unwrap();
-        let expected_package_offset = PackageOffset { package_id: 0, boolean_offset: 0 };
-        assert_eq!(package_offset, expected_package_offset);
+        let expected_package_context = PackageReadContext { package_id: 0, boolean_start_index: 0 };
+        assert_eq!(package_context, expected_package_context);
 
-        let package_offset =
-            get_package_offset(&package_mapped_file, "com.android.aconfig.storage.test_2")
+        let package_context =
+            get_package_read_context(&package_mapped_file, "com.android.aconfig.storage.test_2")
                 .unwrap()
                 .unwrap();
-        let expected_package_offset = PackageOffset { package_id: 1, boolean_offset: 3 };
-        assert_eq!(package_offset, expected_package_offset);
+        let expected_package_context = PackageReadContext { package_id: 1, boolean_start_index: 3 };
+        assert_eq!(package_context, expected_package_context);
 
-        let package_offset =
-            get_package_offset(&package_mapped_file, "com.android.aconfig.storage.test_4")
+        let package_context =
+            get_package_read_context(&package_mapped_file, "com.android.aconfig.storage.test_4")
                 .unwrap()
                 .unwrap();
-        let expected_package_offset = PackageOffset { package_id: 2, boolean_offset: 6 };
-        assert_eq!(package_offset, expected_package_offset);
+        let expected_package_context = PackageReadContext { package_id: 2, boolean_start_index: 6 };
+        assert_eq!(package_context, expected_package_context);
     }
 
     #[test]
-    fn test_none_exist_package_offset_query() {
+    fn test_none_exist_package_context_query() {
         let [_package_map, _flag_map, _flag_val, _flag_info, pb_file] = create_test_storage_files();
         let pb_file_path = pb_file.path().display().to_string();
         // SAFETY:
@@ -99,13 +100,14 @@
             get_mapped_file(&pb_file_path, "mockup", StorageFileType::PackageMap).unwrap()
         };
 
-        let package_offset_option =
-            get_package_offset(&package_mapped_file, "com.android.aconfig.storage.test_3").unwrap();
-        assert_eq!(package_offset_option, None);
+        let package_context_option =
+            get_package_read_context(&package_mapped_file, "com.android.aconfig.storage.test_3")
+                .unwrap();
+        assert_eq!(package_context_option, None);
     }
 
     #[test]
-    fn test_flag_offset_query() {
+    fn test_flag_context_query() {
         let [_package_map, _flag_map, _flag_val, _flag_info, pb_file] = create_test_storage_files();
         let pb_file_path = pb_file.path().display().to_string();
         // SAFETY:
@@ -123,27 +125,29 @@
             (2, "enabled_fixed_ro", StoredFlagType::FixedReadOnlyBoolean, 0u16),
             (0, "disabled_rw", StoredFlagType::ReadWriteBoolean, 0u16),
         ];
-        for (package_id, flag_name, flag_type, flag_id) in baseline.into_iter() {
-            let flag_offset =
-                get_flag_offset(&flag_mapped_file, package_id, flag_name).unwrap().unwrap();
-            assert_eq!(flag_offset.flag_type, flag_type);
-            assert_eq!(flag_offset.flag_id, flag_id);
+        for (package_id, flag_name, flag_type, flag_index) in baseline.into_iter() {
+            let flag_context =
+                get_flag_read_context(&flag_mapped_file, package_id, flag_name).unwrap().unwrap();
+            assert_eq!(flag_context.flag_type, flag_type);
+            assert_eq!(flag_context.flag_index, flag_index);
         }
     }
 
     #[test]
-    fn test_none_exist_flag_offset_query() {
+    fn test_none_exist_flag_context_query() {
         let [_package_map, _flag_map, _flag_val, _flag_info, pb_file] = create_test_storage_files();
         let pb_file_path = pb_file.path().display().to_string();
         // SAFETY:
         // The safety here is ensured as the test process will not write to temp storage file
         let flag_mapped_file =
             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);
+        let flag_context_option =
+            get_flag_read_context(&flag_mapped_file, 0, "none_exist").unwrap();
+        assert_eq!(flag_context_option, None);
 
-        let flag_offset_option = get_flag_offset(&flag_mapped_file, 3, "enabled_ro").unwrap();
-        assert_eq!(flag_offset_option, None);
+        let flag_context_option =
+            get_flag_read_context(&flag_mapped_file, 3, "enabled_ro").unwrap();
+        assert_eq!(flag_context_option, None);
     }
 
     #[test]