Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f17dbcd8 authored by Dennis Shen's avatar Dennis Shen
Browse files

aconfig: update flag info query api

Currently flag info query api is called get_boolean_flag_attribute, in
this change, we switched it over to a flag value type generic
implementation get_flag_attribute. So in the future we want to add more flag value types, this api can stay the same.

Bug: b/312444587
Test: atest -c
Change-Id: I2b272f3fa3cb1d0edc8b77a44bf37752ffe95925
parent ab494001
Loading
Loading
Loading
Loading
+17 −2
Original line number Diff line number Diff line
@@ -106,6 +106,19 @@ Result<MappedStorageFile> get_mapped_file_impl(

} // namespace private internal api

/// Map from StoredFlagType to FlagValueType
android::base::Result<FlagValueType> map_to_flag_value_type(
    StoredFlagType stored_type) {
  switch (stored_type) {
    case StoredFlagType::ReadWriteBoolean:
    case StoredFlagType::ReadOnlyBoolean:
    case StoredFlagType::FixedReadOnlyBoolean:
      return FlagValueType::Boolean;
    default:
      return Error() << "Unsupported stored flag type";
  }
}

/// Get mapped storage file
Result<MappedStorageFile> get_mapped_file(
    std::string const& container,
@@ -178,12 +191,14 @@ Result<bool> get_boolean_flag_value(
}

/// Get boolean flag attribute
Result<uint8_t> get_boolean_flag_attribute(
Result<uint8_t> get_flag_attribute(
    MappedStorageFile const& file,
    FlagValueType value_type,
    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, index);
  auto info_cxx = get_flag_attribute_cxx(
      content, static_cast<uint16_t>(value_type), index);
  if (info_cxx.query_success) {
    return info_cxx.flag_attribute;
  } else {
+9 −2
Original line number Diff line number Diff line
@@ -37,7 +37,6 @@ enum FlagInfoBit {
  HasOverride = 1<<2,
};


/// Mapped storage file
struct MappedStorageFile {
  void* file_ptr;
@@ -68,6 +67,12 @@ android::base::Result<MappedStorageFile> get_mapped_file_impl(

} // namespace private_internal_api

/// Map from StoredFlagType to FlagValueType
/// \input stored_type: stored flag type in the storage file
/// \returns the flag value type enum
android::base::Result<FlagValueType> map_to_flag_value_type(
    StoredFlagType stored_type);

/// Get mapped storage file
/// \input container: stoarge container name
/// \input file_type: storage file type enum
@@ -110,9 +115,11 @@ android::base::Result<bool> get_boolean_flag_value(

/// Get boolean flag attribute
/// \input file: mapped storage file
/// \input value_type: flag value type
/// \input index: the boolean flag index in the file
/// \returns the boolean flag attribute
android::base::Result<uint8_t> get_boolean_flag_attribute(
android::base::Result<uint8_t> get_flag_attribute(
    MappedStorageFile const& file,
    FlagValueType value_type,
    uint32_t index);
} // namespace aconfig_storage
+20 −9
Original line number Diff line number Diff line
@@ -17,11 +17,15 @@
//! flag value query module defines the flag value file read from mapped bytes

use crate::{AconfigStorageError, FILE_VERSION};
use aconfig_storage_file::{flag_info::FlagInfoHeader, read_u8_from_bytes};
use aconfig_storage_file::{flag_info::FlagInfoHeader, read_u8_from_bytes, FlagValueType};
use anyhow::anyhow;

/// Get flag attribute bitfield
pub fn find_boolean_flag_attribute(buf: &[u8], flag_index: u32) -> Result<u8, AconfigStorageError> {
pub fn find_flag_attribute(
    buf: &[u8],
    flag_type: FlagValueType,
    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!(
@@ -31,8 +35,11 @@ pub fn find_boolean_flag_attribute(buf: &[u8], flag_index: u32) -> Result<u8, Ac
        )));
    }

    // 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;
    // get byte offset to the flag info
    let mut head = match flag_type {
        FlagValueType::Boolean => (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."
@@ -53,7 +60,8 @@ mod tests {
    fn test_is_flag_sticky() {
        let flag_info_list = create_test_flag_info_list().into_bytes();
        for offset in 0..8 {
            let attribute = find_boolean_flag_attribute(&flag_info_list[..], offset).unwrap();
            let attribute =
                find_flag_attribute(&flag_info_list[..], FlagValueType::Boolean, offset).unwrap();
            assert_eq!((attribute & FlagInfoBit::IsSticky as u8) != 0u8, false);
        }
    }
@@ -64,7 +72,8 @@ mod tests {
        let flag_info_list = create_test_flag_info_list().into_bytes();
        let baseline: Vec<bool> = vec![true, false, true, false, false, false, false, false];
        for offset in 0..8 {
            let attribute = find_boolean_flag_attribute(&flag_info_list[..], offset).unwrap();
            let attribute =
                find_flag_attribute(&flag_info_list[..], FlagValueType::Boolean, offset).unwrap();
            assert_eq!(
                (attribute & FlagInfoBit::IsReadWrite as u8) != 0u8,
                baseline[offset as usize]
@@ -77,7 +86,8 @@ mod tests {
    fn test_flag_has_override() {
        let flag_info_list = create_test_flag_info_list().into_bytes();
        for offset in 0..8 {
            let attribute = find_boolean_flag_attribute(&flag_info_list[..], offset).unwrap();
            let attribute =
                find_flag_attribute(&flag_info_list[..], FlagValueType::Boolean, offset).unwrap();
            assert_eq!((attribute & FlagInfoBit::HasOverride as u8) != 0u8, false);
        }
    }
@@ -86,7 +96,8 @@ mod tests {
    // this test point locks down query beyond the end of boolean section
    fn test_boolean_out_of_range() {
        let flag_info_list = create_test_flag_info_list().into_bytes();
        let error = find_boolean_flag_attribute(&flag_info_list[..], 8).unwrap_err();
        let error =
            find_flag_attribute(&flag_info_list[..], FlagValueType::Boolean, 8).unwrap_err();
        assert_eq!(
            format!("{:?}", error),
            "InvalidStorageFileOffset(Flag info offset goes beyond the end of the file.)"
@@ -99,7 +110,7 @@ mod tests {
        let mut info_list = create_test_flag_info_list();
        info_list.header.version = crate::FILE_VERSION + 1;
        let flag_info = info_list.into_bytes();
        let error = find_boolean_flag_attribute(&flag_info[..], 4).unwrap_err();
        let error = find_flag_attribute(&flag_info[..], FlagValueType::Boolean, 4).unwrap_err();
        assert_eq!(
            format!("{:?}", error),
            format!(
+31 −18
Original line number Diff line number Diff line
@@ -45,12 +45,12 @@ pub mod package_table_query;
#[cfg(test)]
mod test_utils;

pub use aconfig_storage_file::{AconfigStorageError, StorageFileType};
pub use aconfig_storage_file::{AconfigStorageError, FlagValueType, StorageFileType};
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_info_query::find_flag_attribute;
use flag_table_query::find_flag_read_context;
use flag_value_query::find_boolean_flag_value;
use package_table_query::find_package_read_context;
@@ -149,16 +149,21 @@ pub fn get_storage_file_version(file_path: &str) -> Result<u32, AconfigStorageEr
    read_u32_from_bytes(&buffer, &mut head)
}

/// Get the boolean flag attribute.
/// Get the flag attribute.
///
/// \input file: mapped flag info file
/// \input index: boolean flag index
/// \input flag_type: flag value type
/// \input flag_index: flag index
///
/// \return
/// If the provide offset is valid, it returns the boolean flag attribute bitfiled, otherwise it
/// If the provide offset is valid, it returns the flag attribute bitfiled, otherwise it
/// returns the error message.
pub fn get_boolean_flag_attribute(file: &Mmap, index: u32) -> Result<u8, AconfigStorageError> {
    find_boolean_flag_attribute(file, index)
pub fn get_flag_attribute(
    file: &Mmap,
    flag_type: FlagValueType,
    flag_index: u32,
) -> Result<u8, AconfigStorageError> {
    find_flag_attribute(file, flag_type, flag_index)
}

// *************************************** //
@@ -201,7 +206,7 @@ mod ffi {
    }

    // Flag info query return for cc interlop
    pub struct BooleanFlagAttributeQueryCXX {
    pub struct FlagAttributeQueryCXX {
        pub query_success: bool,
        pub error_message: String,
        pub flag_attribute: u8,
@@ -224,10 +229,11 @@ mod ffi {

        pub fn get_boolean_flag_value_cxx(file: &[u8], offset: u32) -> BooleanFlagValueQueryCXX;

        pub fn get_boolean_flag_attribute_cxx(
        pub fn get_flag_attribute_cxx(
            file: &[u8],
            offset: u32,
        ) -> BooleanFlagAttributeQueryCXX;
            flag_type: u16,
            flag_index: u32,
        ) -> FlagAttributeQueryCXX;
    }
}

@@ -312,7 +318,7 @@ impl ffi::BooleanFlagValueQueryCXX {
}

/// Implement the flag info interlop return type, create from actual flag info api return type
impl ffi::BooleanFlagAttributeQueryCXX {
impl ffi::FlagAttributeQueryCXX {
    pub(crate) fn new(info_result: Result<u8, AconfigStorageError>) -> Self {
        match info_result {
            Ok(info) => {
@@ -365,12 +371,18 @@ pub fn get_boolean_flag_value_cxx(file: &[u8], offset: u32) -> ffi::BooleanFlagV
    ffi::BooleanFlagValueQueryCXX::new(find_boolean_flag_value(file, offset))
}

/// Get boolean flag attribute cc interlop
pub fn get_boolean_flag_attribute_cxx(
/// Get flag attribute cc interlop
pub fn get_flag_attribute_cxx(
    file: &[u8],
    offset: u32,
) -> ffi::BooleanFlagAttributeQueryCXX {
    ffi::BooleanFlagAttributeQueryCXX::new(find_boolean_flag_attribute(file, offset))
    flag_type: u16,
    flag_index: u32,
) -> ffi::FlagAttributeQueryCXX {
    match FlagValueType::try_from(flag_type) {
        Ok(value_type) => {
            ffi::FlagAttributeQueryCXX::new(find_flag_attribute(file, value_type, flag_index))
        }
        Err(errmsg) => ffi::FlagAttributeQueryCXX::new(Err(errmsg)),
    }
}

/// Get storage version number cc interlop
@@ -494,7 +506,8 @@ files {{
            unsafe { get_mapped_file(&pb_file_path, "mockup", StorageFileType::FlagInfo).unwrap() };
        let is_rw: Vec<bool> = vec![true, false, true, false, false, false, false, false];
        for (offset, expected_value) in is_rw.into_iter().enumerate() {
            let attribute = get_boolean_flag_attribute(&flag_info_file, offset as u32).unwrap();
            let attribute =
                get_flag_attribute(&flag_info_file, FlagValueType::Boolean, offset as u32).unwrap();
            assert!((attribute & FlagInfoBit::IsSticky as u8) == 0u8);
            assert_eq!((attribute & FlagInfoBit::IsReadWrite as u8) != 0u8, expected_value);
            assert!((attribute & FlagInfoBit::HasOverride as u8) == 0u8);
+2 −2
Original line number Diff line number Diff line
@@ -234,7 +234,7 @@ TEST_F(AconfigStorageTest, test_boolean_flag_info_query) {
  auto expected_value = std::vector<bool>{
    true, false, true, false, false, false, false, false};
  for (int index = 0; index < 8; ++index) {
    auto attribute = api::get_boolean_flag_attribute(*mapped_file, index);
    auto attribute = api::get_flag_attribute(*mapped_file, api::FlagValueType::Boolean, 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,
@@ -249,7 +249,7 @@ TEST_F(AconfigStorageTest, test_invalid_boolean_flag_info_query) {
      storage_record_pb, "mockup", api::StorageFileType::flag_info);
  ASSERT_TRUE(mapped_file.ok());

  auto attribute = api::get_boolean_flag_attribute(*mapped_file, 8);
  auto attribute = api::get_flag_attribute(*mapped_file, api::FlagValueType::Boolean, 8);
  ASSERT_FALSE(attribute.ok());
  ASSERT_EQ(attribute.error().message(),
            std::string("InvalidStorageFileOffset(Flag info offset goes beyond the end of the file.)"));
Loading