Loading tools/aconfig/aconfig_storage_file/src/lib.rs +18 −2 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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, Loading @@ -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)] Loading Loading @@ -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 Loading tools/aconfig/aconfig_storage_read_api/include/aconfig_storage/aconfig_storage_read_api.hpp +25 −15 Original line number Diff line number Diff line Loading @@ -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, Loading @@ -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; Loading @@ -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; Loading Loading @@ -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 Loading tools/aconfig/aconfig_storage_write_api/Android.bp +2 −0 Original line number Diff line number Diff line Loading @@ -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", Loading Loading @@ -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", Loading tools/aconfig/aconfig_storage_write_api/aconfig_storage_write_api.cpp +68 −21 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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"; Loading @@ -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; Loading @@ -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>( Loading @@ -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, Loading tools/aconfig/aconfig_storage_write_api/include/aconfig_storage/aconfig_storage_write_api.hpp +24 −7 Original line number Diff line number Diff line Loading @@ -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; }; Loading @@ -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 Loading
tools/aconfig/aconfig_storage_file/src/lib.rs +18 −2 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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, Loading @@ -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)] Loading Loading @@ -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 Loading
tools/aconfig/aconfig_storage_read_api/include/aconfig_storage/aconfig_storage_read_api.hpp +25 −15 Original line number Diff line number Diff line Loading @@ -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, Loading @@ -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; Loading @@ -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; Loading Loading @@ -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 Loading
tools/aconfig/aconfig_storage_write_api/Android.bp +2 −0 Original line number Diff line number Diff line Loading @@ -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", Loading Loading @@ -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", Loading
tools/aconfig/aconfig_storage_write_api/aconfig_storage_write_api.cpp +68 −21 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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"; Loading @@ -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; Loading @@ -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>( Loading @@ -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, Loading
tools/aconfig/aconfig_storage_write_api/include/aconfig_storage/aconfig_storage_write_api.hpp +24 −7 Original line number Diff line number Diff line Loading @@ -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; }; Loading @@ -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