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

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

aconfig: create flag info file write c api

Bug: b/312444587
Test: atest -c
Change-Id: I310e1ed727ced454bec2016afe48f7a29561fac3
parent 4647c0e1
Loading
Loading
Loading
Loading
+18 −2
Original line number Diff line number Diff line
@@ -51,7 +51,9 @@ 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, InvalidStoredFlagType};
use crate::AconfigStorageError::{
    BytesParseFail, HashTableSizeLimit, InvalidFlagValueType, InvalidStoredFlagType,
};

/// Storage file version
pub const FILE_VERSION: u32 = 1;
@@ -125,7 +127,7 @@ impl TryFrom<u16> for StoredFlagType {
}

/// Flag value type enum, one FlagValueType maps to many StoredFlagType
/// ONLY APPEND, NEVER REMOVE FOR BACKWARD COMPATIBILITY.
/// ONLY APPEND, NEVER REMOVE FOR BACKWARD COMPATIBILITY. THE MAX IS U16
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum FlagValueType {
    Boolean = 0,
@@ -143,6 +145,17 @@ impl TryFrom<StoredFlagType> for FlagValueType {
    }
}

impl TryFrom<u16> for FlagValueType {
    type Error = AconfigStorageError;

    fn try_from(value: u16) -> Result<Self, Self::Error> {
        match value {
            x if x == Self::Boolean as u16 => Ok(Self::Boolean),
            _ => Err(InvalidFlagValueType(anyhow!("Invalid flag value type"))),
        }
    }
}

/// Storage query api error
#[non_exhaustive]
#[derive(thiserror::Error, Debug)]
@@ -182,6 +195,9 @@ pub enum AconfigStorageError {

    #[error("invalid stored flag type")]
    InvalidStoredFlagType(#[source] anyhow::Error),

    #[error("invalid flag value type")]
    InvalidFlagValueType(#[source] anyhow::Error),
}

/// Get the right hash table size given number of entries in the table. Use a
+25 −15
Original line number Diff line number Diff line
@@ -6,7 +6,8 @@

namespace aconfig_storage {

/// Storage file type enum
/// Storage file type enum, to be consistent with the one defined in
/// aconfig_storage_file/src/lib.rs
enum StorageFileType {
  package_map,
  flag_map,
@@ -14,6 +15,29 @@ enum StorageFileType {
  flag_info
};

/// Flag type enum, to be consistent with the one defined in
/// aconfig_storage_file/src/lib.rs
enum StoredFlagType {
  ReadWriteBoolean = 0,
  ReadOnlyBoolean = 1,
  FixedReadOnlyBoolean = 2,
};

/// Flag value type enum, to be consistent with the one defined in
/// aconfig_storage_file/src/lib.rs
enum FlagValueType {
  Boolean = 0,
};

/// Flag info enum, to be consistent with the one defined in
/// aconfig_storage_file/src/flag_info.rs
enum FlagInfoBit {
  IsSticky = 1<<0,
  IsReadWrite = 1<<1,
  HasOverride = 1<<2,
};


/// Mapped storage file
struct MappedStorageFile {
  void* file_ptr;
@@ -27,13 +51,6 @@ struct PackageReadContext {
  uint32_t boolean_start_index;
};

/// Flag type enum, to be consistent with the one defined in aconfig_storage_file/src/lib.rs
enum StoredFlagType {
  ReadWriteBoolean = 0,
  ReadOnlyBoolean = 1,
  FixedReadOnlyBoolean = 2,
};

/// Flag read context query result
struct FlagReadContext {
  bool flag_exists;
@@ -91,13 +108,6 @@ android::base::Result<bool> get_boolean_flag_value(
    MappedStorageFile const& file,
    uint32_t index);

/// Flag info enum, to be consistent with the one defined in aconfig_storage_file/src/lib.rs
enum FlagInfoBit {
  IsSticky = 1<<0,
  IsReadWrite = 1<<1,
  HasOverride = 1<<2,
};

/// Get boolean flag attribute
/// \input file: mapped storage file
/// \input index: the boolean flag index in the file
+2 −0
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ rust_test_host {
    defaults: ["aconfig_storage_write_api.defaults"],
    data: [
        "tests/flag.val",
        "tests/flag.info",
    ],
    rustlibs: [
        "libaconfig_storage_read_api",
@@ -75,6 +76,7 @@ cc_library_static {
    whole_static_libs: ["libaconfig_storage_write_api_cxx_bridge"],
    export_include_dirs: ["include"],
    static_libs: [
        "libaconfig_storage_read_api_cc",
        "libaconfig_storage_protos_cc",
        "libprotobuf-cpp-lite",
        "libbase",
+68 −21
Original line number Diff line number Diff line
@@ -38,7 +38,8 @@ static Result<storage_records_pb> read_storage_records_pb(std::string const& pb_
/// Get storage file path
static Result<std::string> find_storage_file(
    std::string const& pb_file,
    std::string const& container) {
    std::string const& container,
    StorageFileType file_type) {
  auto records_pb = read_storage_records_pb(pb_file);
  if (!records_pb.ok()) {
    return Error() << "Unable to read storage records from " << pb_file
@@ -47,15 +48,26 @@ static Result<std::string> find_storage_file(

  for (auto& entry : records_pb->files()) {
    if (entry.container() == container) {
      switch(file_type) {
        case StorageFileType::package_map:
          return entry.package_map();
        case StorageFileType::flag_map:
          return entry.flag_map();
        case StorageFileType::flag_val:
          return entry.flag_val();
        case StorageFileType::flag_info:
          return entry.flag_info();
        default:
          return Error() << "Invalid file type " << file_type;
      }
    }
  }

  return Error() << "Unable to find storage files for container " << container;;
  return Error() << "Unable to find storage files for container " << container;
}

/// Map a storage file
static Result<MappedFlagValueFile> map_storage_file(std::string const& file) {
static Result<MutableMappedStorageFile> map_storage_file(std::string const& file) {
  struct stat file_stat;
  if (stat(file.c_str(), &file_stat) < 0) {
    return ErrnoError() << "stat failed";
@@ -78,7 +90,7 @@ static Result<MappedFlagValueFile> map_storage_file(std::string const& file) {
    return ErrnoError() << "mmap failed";
  }

  auto mapped_file = MappedFlagValueFile();
  auto mapped_file = MutableMappedStorageFile();
  mapped_file.file_ptr = map_result;
  mapped_file.file_size = file_size;

@@ -87,34 +99,37 @@ static Result<MappedFlagValueFile> map_storage_file(std::string const& file) {

namespace private_internal_api {

/// Get mapped file implementation.
Result<MappedFlagValueFile> get_mapped_flag_value_file_impl(
/// Get mutable mapped file implementation.
Result<MutableMappedStorageFile> get_mutable_mapped_file_impl(
    std::string const& pb_file,
    std::string const& container) {
  auto file_result = find_storage_file(pb_file, container);
    std::string const& container,
    StorageFileType file_type) {
  if (file_type != StorageFileType::flag_val &&
      file_type != StorageFileType::flag_info) {
    return Error() << "Cannot create mutable mapped file for this file type";
  }

  auto file_result = find_storage_file(pb_file, container, file_type);
  if (!file_result.ok()) {
    return Error() << file_result.error();
  }
  auto mapped_result = map_storage_file(*file_result);
  if (!mapped_result.ok()) {
    return Error() << "failed to map " << *file_result << ": "
                   << mapped_result.error();
  }
  return *mapped_result;

  return map_storage_file(*file_result);
}

} // namespace private internal api

/// Get mapped writeable flag value file
Result<MappedFlagValueFile> get_mapped_flag_value_file(
    std::string const& container) {
  return private_internal_api::get_mapped_flag_value_file_impl(
      kPersistStorageRecordsPb, container);
/// Get mutable mapped file
Result<MutableMappedStorageFile> get_mutable_mapped_file(
    std::string const& container,
    StorageFileType file_type) {
  return private_internal_api::get_mutable_mapped_file_impl(
      kPersistStorageRecordsPb, container, file_type);
}

/// Set boolean flag value
Result<void> set_boolean_flag_value(
    const MappedFlagValueFile& file,
    const MutableMappedStorageFile& file,
    uint32_t offset,
    bool value) {
  auto content = rust::Slice<uint8_t>(
@@ -126,6 +141,38 @@ Result<void> set_boolean_flag_value(
  return {};
}

/// Set if flag is sticky
Result<void> set_flag_is_sticky(
    const MutableMappedStorageFile& file,
    FlagValueType value_type,
    uint32_t offset,
    bool value) {
  auto content = rust::Slice<uint8_t>(
      static_cast<uint8_t*>(file.file_ptr), file.file_size);
  auto update_cxx = update_flag_is_sticky_cxx(
      content, static_cast<uint16_t>(value_type), offset, value);
  if (!update_cxx.update_success) {
    return Error() << std::string(update_cxx.error_message.c_str());
  }
  return {};
}

/// Set if flag has override
Result<void> set_flag_has_override(
    const MutableMappedStorageFile& file,
    FlagValueType value_type,
    uint32_t offset,
    bool value) {
  auto content = rust::Slice<uint8_t>(
      static_cast<uint8_t*>(file.file_ptr), file.file_size);
  auto update_cxx = update_flag_has_override_cxx(
      content, static_cast<uint16_t>(value_type), offset, value);
  if (!update_cxx.update_success) {
    return Error() << std::string(update_cxx.error_message.c_str());
  }
  return {};
}

Result<void> create_flag_info(
    std::string const& package_map,
    std::string const& flag_map,
+24 −7
Original line number Diff line number Diff line
@@ -4,13 +4,14 @@
#include <string>

#include <android-base/result.h>
#include <aconfig_storage/aconfig_storage_read_api.hpp>

using namespace android::base;

namespace aconfig_storage {

/// Mapped flag value file
struct MappedFlagValueFile{
struct MutableMappedStorageFile{
  void* file_ptr;
  size_t file_size;
};
@@ -18,19 +19,35 @@ struct MappedFlagValueFile{
/// DO NOT USE APIS IN THE FOLLOWING NAMESPACE DIRECTLY
namespace private_internal_api {

Result<MappedFlagValueFile> get_mapped_flag_value_file_impl(
Result<MutableMappedStorageFile> get_mutable_mapped_file_impl(
    std::string const& pb_file,
    std::string const& container);
    std::string const& container,
    StorageFileType file_type);

} // namespace private_internal_api

/// Get mapped writeable flag value file
Result<MappedFlagValueFile> get_mapped_flag_value_file(
    std::string const& container);
/// Get mapped writeable storage file
Result<MutableMappedStorageFile> get_mutable_mapped_file(
    std::string const& container,
    StorageFileType file_type);

/// Set boolean flag value
Result<void> set_boolean_flag_value(
    const MappedFlagValueFile& file,
    const MutableMappedStorageFile& file,
    uint32_t offset,
    bool value);

/// Set if flag is sticky
Result<void> set_flag_is_sticky(
    const MutableMappedStorageFile& file,
    FlagValueType value_type,
    uint32_t offset,
    bool value);

/// Set if flag has override
Result<void> set_flag_has_override(
    const MutableMappedStorageFile& file,
    FlagValueType value_type,
    uint32_t offset,
    bool value);

Loading