Loading tools/aconfig/aconfig/src/codegen/cpp.rs +4 −0 Original line number Original line Diff line number Diff line Loading @@ -45,6 +45,8 @@ where let header = package.replace('.', "_"); let header = package.replace('.', "_"); let package_macro = header.to_uppercase(); let package_macro = header.to_uppercase(); let cpp_namespace = package.replace('.', "::"); let cpp_namespace = package.replace('.', "::"); ensure!(class_elements.len() > 0); let container = class_elements[0].container.clone(); ensure!(codegen::is_valid_name_ident(&header)); ensure!(codegen::is_valid_name_ident(&header)); let context = Context { let context = Context { header: &header, header: &header, Loading @@ -56,6 +58,7 @@ where readwrite_count, readwrite_count, is_test_mode: codegen_mode == CodegenMode::Test, is_test_mode: codegen_mode == CodegenMode::Test, class_elements, class_elements, container, allow_instrumentation, allow_instrumentation, }; }; Loading Loading @@ -100,6 +103,7 @@ pub struct Context<'a> { pub readwrite_count: i32, pub readwrite_count: i32, pub is_test_mode: bool, pub is_test_mode: bool, pub class_elements: Vec<ClassElement>, pub class_elements: Vec<ClassElement>, pub container: String, pub allow_instrumentation: bool, pub allow_instrumentation: bool, } } Loading tools/aconfig/aconfig/src/codegen/rust.rs +756 −20 File changed.Preview size limit exceeded, changes collapsed. Show changes tools/aconfig/aconfig/src/commands.rs +13 −3 Original line number Original line Diff line number Diff line Loading @@ -238,7 +238,11 @@ pub fn create_cpp_lib( ) ) } } pub fn create_rust_lib(mut input: Input, codegen_mode: CodegenMode) -> Result<OutputFile> { pub fn create_rust_lib( mut input: Input, codegen_mode: CodegenMode, allow_instrumentation: bool, ) -> Result<OutputFile> { // // TODO(327420679): Enable export mode for native flag library // // TODO(327420679): Enable export mode for native flag library ensure!( ensure!( codegen_mode != CodegenMode::Exported, codegen_mode != CodegenMode::Exported, Loading @@ -250,8 +254,14 @@ pub fn create_rust_lib(mut input: Input, codegen_mode: CodegenMode) -> Result<Ou bail!("no parsed flags, or the parsed flags use different packages"); bail!("no parsed flags, or the parsed flags use different packages"); }; }; let package = package.to_string(); let package = package.to_string(); let _flag_ids = assign_flag_ids(&package, modified_parsed_flags.iter())?; let flag_ids = assign_flag_ids(&package, modified_parsed_flags.iter())?; generate_rust_code(&package, modified_parsed_flags.into_iter(), codegen_mode) generate_rust_code( &package, flag_ids, modified_parsed_flags.into_iter(), codegen_mode, allow_instrumentation, ) } } pub fn create_storage( pub fn create_storage( Loading tools/aconfig/aconfig/src/main.rs +10 −2 Original line number Original line Diff line number Diff line Loading @@ -101,6 +101,12 @@ fn cli() -> Command { Command::new("create-rust-lib") Command::new("create-rust-lib") .arg(Arg::new("cache").long("cache").required(true)) .arg(Arg::new("cache").long("cache").required(true)) .arg(Arg::new("out").long("out").required(true)) .arg(Arg::new("out").long("out").required(true)) .arg( Arg::new("allow-instrumentation") .long("allow-instrumentation") .value_parser(clap::value_parser!(bool)) .default_value("false"), ) .arg( .arg( Arg::new("mode") Arg::new("mode") .long("mode") .long("mode") Loading Loading @@ -267,8 +273,10 @@ fn main() -> Result<()> { Some(("create-rust-lib", sub_matches)) => { Some(("create-rust-lib", sub_matches)) => { let cache = open_single_file(sub_matches, "cache")?; let cache = open_single_file(sub_matches, "cache")?; let mode = get_required_arg::<CodegenMode>(sub_matches, "mode")?; let mode = get_required_arg::<CodegenMode>(sub_matches, "mode")?; let generated_file = let allow_instrumentation = commands::create_rust_lib(cache, *mode).context("failed to create rust lib")?; get_required_arg::<bool>(sub_matches, "allow-instrumentation")?; let generated_file = commands::create_rust_lib(cache, *mode, *allow_instrumentation) .context("failed to create rust lib")?; let dir = PathBuf::from(get_required_arg::<String>(sub_matches, "out")?); let dir = PathBuf::from(get_required_arg::<String>(sub_matches, "out")?); write_output_file_realtive_to_dir(&dir, &generated_file)?; write_output_file_realtive_to_dir(&dir, &generated_file)?; } } Loading tools/aconfig/aconfig/templates/cpp_source_file.template +108 −65 Original line number Original line Diff line number Diff line #include "{header}.h" #include "{header}.h" {{ if allow_instrumentation }} {{ if allow_instrumentation }} {{ if readwrite- }} #include <sys/stat.h> #include <sys/stat.h> #include "aconfig_storage/aconfig_storage_read_api.hpp" #include "aconfig_storage/aconfig_storage_read_api.hpp" #include <android/log.h> #include <android/log.h> #define LOG_TAG "aconfig_cpp_codegen" #define ALOGI(msg, ...) \ #define ALOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__) __android_log_print(ANDROID_LOG_INFO, "AconfigTestMission1", (msg), __VA_ARGS__) {{ -endif }} {{ endif }} {{ endif }} {{ if readwrite- }} {{ if readwrite- }} Loading Loading @@ -66,8 +66,68 @@ namespace {cpp_namespace} \{ class flag_provider : public flag_provider_interface \{ class flag_provider : public flag_provider_interface \{ public: public: {{ -for item in class_elements }} {{ if allow_instrumentation- }} {{ if readwrite- }} flag_provider() {{ if readwrite- }} : cache_({readwrite_count}, -1) , boolean_start_index_() {{ -else- }} : boolean_start_index_() {{ -endif }} , flag_value_file_(nullptr) , read_from_new_storage_(false) , use_new_storage_value(false) \{ struct stat buffer; if (stat("/metadata/aconfig_test_missions/mission_1", &buffer) == 0) \{ read_from_new_storage_ = true; } else \{ return; } auto package_map_file = aconfig_storage::get_mapped_file( "{container}", aconfig_storage::StorageFileType::package_map); if (!package_map_file.ok()) \{ ALOGI("error: failed to get package map file: %s", package_map_file.error().c_str()); return; } auto context = aconfig_storage::get_package_read_context( **package_map_file, "{package}"); if (!context.ok()) \{ ALOGI("error: failed to get package read context: %s", context.error().c_str()); return; } // cache package boolean flag start index boolean_start_index_ = context->boolean_start_index; // unmap package map file and free memory delete *package_map_file; auto flag_value_file = aconfig_storage::get_mapped_file( "{container}", aconfig_storage::StorageFileType::flag_val); if (!flag_value_file.ok()) \{ ALOGI("error: failed to get flag value file: %s", flag_value_file.error().c_str()); return; } // cache flag value file flag_value_file_ = std::unique_ptr<aconfig_storage::MappedStorageFile>( *flag_value_file); use_new_storage_value = server_configurable_flags::GetServerConfigurableFlag( "aconfig_flags.core_experiments_team_internal", "com.android.providers.settings.use_new_storage_value", "false") == "true"; } {{ -endif }} {{ -endif }} {{ -for item in class_elements }} virtual bool {item.flag_name}() override \{ virtual bool {item.flag_name}() override \{ {{ -if item.readwrite }} {{ -if item.readwrite }} if (cache_[{item.readwrite_idx}] == -1) \{ if (cache_[{item.readwrite_idx}] == -1) \{ Loading @@ -76,6 +136,39 @@ namespace {cpp_namespace} \{ "{item.device_config_flag}", "{item.device_config_flag}", "{item.default_value}") == "true"; "{item.default_value}") == "true"; } } {{ if allow_instrumentation- }} if (read_from_new_storage_) \{ if (!flag_value_file_) \{ ALOGI("error: failed to get flag {item.flag_name}: flag value file is null"); return cache_[{item.readwrite_idx}]; } auto value = aconfig_storage::get_boolean_flag_value( *flag_value_file_, boolean_start_index_ + {item.flag_offset}); if (!value.ok()) \{ ALOGI("error: failed to read flag value: %s", value.error().c_str()); return cache_[{item.readwrite_idx}]; } bool expected_value = cache_[{item.readwrite_idx}]; if (*value != expected_value) \{ ALOGI("error: {item.flag_name} value mismatch, new storage value is %s, old storage value is %s", *value ? "true" : "false", expected_value ? "true" : "false"); } if (use_new_storage_value) \{ return *value; } else \{ return expected_value; } } {{ -endif }} return cache_[{item.readwrite_idx}]; return cache_[{item.readwrite_idx}]; {{ -else }} {{ -else }} {{ -if item.is_fixed_read_only }} {{ -if item.is_fixed_read_only }} Loading @@ -86,12 +179,21 @@ namespace {cpp_namespace} \{ {{ -endif }} {{ -endif }} } } {{ -endfor }} {{ -endfor }} {{ if readwrite- }} {{ if readwrite- }} private: private: std::vector<int8_t> cache_ = std::vector<int8_t>({readwrite_count}, -1); std::vector<int8_t> cache_ = std::vector<int8_t>({readwrite_count}, -1); {{ if allow_instrumentation- }} uint32_t boolean_start_index_; std::unique_ptr<aconfig_storage::MappedStorageFile> flag_value_file_; bool read_from_new_storage_; bool use_new_storage_value; {{ -endif }} {{ -endif }} {{ -endif }} }; }; {{ -endif }} {{ -endif }} Loading @@ -107,62 +209,6 @@ bool {header}_{item.flag_name}() \{ {{ -if item.readwrite }} {{ -if item.readwrite }} return {cpp_namespace}::{item.flag_name}(); return {cpp_namespace}::{item.flag_name}(); {{ -else }} {{ -else }} {{ if allow_instrumentation }} auto result = {{ if item.is_fixed_read_only }} {package_macro}_{item.flag_macro} {{ else }} {item.default_value} {{ endif }}; struct stat buffer; if (stat("/metadata/aconfig_test_missions/mission_1", &buffer) != 0) \{ return result; } auto package_map_file = aconfig_storage::get_mapped_file( "{item.container}", aconfig_storage::StorageFileType::package_map); if (!package_map_file.ok()) \{ ALOGI("error: failed to get package map file: %s", package_map_file.error().c_str()); return result; } auto package_read_context = aconfig_storage::get_package_read_context( **package_map_file, "{package}"); if (!package_read_context.ok()) \{ ALOGI("error: failed to get package read context: %s", package_map_file.error().c_str()); return result; } delete *package_map_file; auto flag_val_map = aconfig_storage::get_mapped_file( "{item.container}", aconfig_storage::StorageFileType::flag_val); if (!flag_val_map.ok()) \{ ALOGI("error: failed to get flag val map: %s", package_map_file.error().c_str()); return result; } auto value = aconfig_storage::get_boolean_flag_value( **flag_val_map, package_read_context->boolean_start_index + {item.flag_offset}); if (!value.ok()) \{ ALOGI("error: failed to get flag val: %s", package_map_file.error().c_str()); return result; } delete *flag_val_map; if (*value != result) \{ ALOGI("error: new storage value '%d' does not match current value '%d'", *value, result); } else \{ ALOGI("success: new storage value was '%d, legacy storage was '%d'", *value, result); } return result; {{ else }} {{ -if item.is_fixed_read_only }} {{ -if item.is_fixed_read_only }} return {package_macro}_{item.flag_macro}; return {package_macro}_{item.flag_macro}; {{ -else }} {{ -else }} Loading @@ -170,7 +216,6 @@ bool {header}_{item.flag_name}() \{ {{ -endif }} {{ -endif }} {{ -endif }} {{ -endif }} {{ -endif }} {{ -endif }} {{ -endif }} } } {{ -if is_test_mode }} {{ -if is_test_mode }} Loading @@ -185,5 +230,3 @@ void {header}_reset_flags() \{ {cpp_namespace}::reset_flags(); {cpp_namespace}::reset_flags(); } } {{ -endif }} {{ -endif }} Loading
tools/aconfig/aconfig/src/codegen/cpp.rs +4 −0 Original line number Original line Diff line number Diff line Loading @@ -45,6 +45,8 @@ where let header = package.replace('.', "_"); let header = package.replace('.', "_"); let package_macro = header.to_uppercase(); let package_macro = header.to_uppercase(); let cpp_namespace = package.replace('.', "::"); let cpp_namespace = package.replace('.', "::"); ensure!(class_elements.len() > 0); let container = class_elements[0].container.clone(); ensure!(codegen::is_valid_name_ident(&header)); ensure!(codegen::is_valid_name_ident(&header)); let context = Context { let context = Context { header: &header, header: &header, Loading @@ -56,6 +58,7 @@ where readwrite_count, readwrite_count, is_test_mode: codegen_mode == CodegenMode::Test, is_test_mode: codegen_mode == CodegenMode::Test, class_elements, class_elements, container, allow_instrumentation, allow_instrumentation, }; }; Loading Loading @@ -100,6 +103,7 @@ pub struct Context<'a> { pub readwrite_count: i32, pub readwrite_count: i32, pub is_test_mode: bool, pub is_test_mode: bool, pub class_elements: Vec<ClassElement>, pub class_elements: Vec<ClassElement>, pub container: String, pub allow_instrumentation: bool, pub allow_instrumentation: bool, } } Loading
tools/aconfig/aconfig/src/codegen/rust.rs +756 −20 File changed.Preview size limit exceeded, changes collapsed. Show changes
tools/aconfig/aconfig/src/commands.rs +13 −3 Original line number Original line Diff line number Diff line Loading @@ -238,7 +238,11 @@ pub fn create_cpp_lib( ) ) } } pub fn create_rust_lib(mut input: Input, codegen_mode: CodegenMode) -> Result<OutputFile> { pub fn create_rust_lib( mut input: Input, codegen_mode: CodegenMode, allow_instrumentation: bool, ) -> Result<OutputFile> { // // TODO(327420679): Enable export mode for native flag library // // TODO(327420679): Enable export mode for native flag library ensure!( ensure!( codegen_mode != CodegenMode::Exported, codegen_mode != CodegenMode::Exported, Loading @@ -250,8 +254,14 @@ pub fn create_rust_lib(mut input: Input, codegen_mode: CodegenMode) -> Result<Ou bail!("no parsed flags, or the parsed flags use different packages"); bail!("no parsed flags, or the parsed flags use different packages"); }; }; let package = package.to_string(); let package = package.to_string(); let _flag_ids = assign_flag_ids(&package, modified_parsed_flags.iter())?; let flag_ids = assign_flag_ids(&package, modified_parsed_flags.iter())?; generate_rust_code(&package, modified_parsed_flags.into_iter(), codegen_mode) generate_rust_code( &package, flag_ids, modified_parsed_flags.into_iter(), codegen_mode, allow_instrumentation, ) } } pub fn create_storage( pub fn create_storage( Loading
tools/aconfig/aconfig/src/main.rs +10 −2 Original line number Original line Diff line number Diff line Loading @@ -101,6 +101,12 @@ fn cli() -> Command { Command::new("create-rust-lib") Command::new("create-rust-lib") .arg(Arg::new("cache").long("cache").required(true)) .arg(Arg::new("cache").long("cache").required(true)) .arg(Arg::new("out").long("out").required(true)) .arg(Arg::new("out").long("out").required(true)) .arg( Arg::new("allow-instrumentation") .long("allow-instrumentation") .value_parser(clap::value_parser!(bool)) .default_value("false"), ) .arg( .arg( Arg::new("mode") Arg::new("mode") .long("mode") .long("mode") Loading Loading @@ -267,8 +273,10 @@ fn main() -> Result<()> { Some(("create-rust-lib", sub_matches)) => { Some(("create-rust-lib", sub_matches)) => { let cache = open_single_file(sub_matches, "cache")?; let cache = open_single_file(sub_matches, "cache")?; let mode = get_required_arg::<CodegenMode>(sub_matches, "mode")?; let mode = get_required_arg::<CodegenMode>(sub_matches, "mode")?; let generated_file = let allow_instrumentation = commands::create_rust_lib(cache, *mode).context("failed to create rust lib")?; get_required_arg::<bool>(sub_matches, "allow-instrumentation")?; let generated_file = commands::create_rust_lib(cache, *mode, *allow_instrumentation) .context("failed to create rust lib")?; let dir = PathBuf::from(get_required_arg::<String>(sub_matches, "out")?); let dir = PathBuf::from(get_required_arg::<String>(sub_matches, "out")?); write_output_file_realtive_to_dir(&dir, &generated_file)?; write_output_file_realtive_to_dir(&dir, &generated_file)?; } } Loading
tools/aconfig/aconfig/templates/cpp_source_file.template +108 −65 Original line number Original line Diff line number Diff line #include "{header}.h" #include "{header}.h" {{ if allow_instrumentation }} {{ if allow_instrumentation }} {{ if readwrite- }} #include <sys/stat.h> #include <sys/stat.h> #include "aconfig_storage/aconfig_storage_read_api.hpp" #include "aconfig_storage/aconfig_storage_read_api.hpp" #include <android/log.h> #include <android/log.h> #define LOG_TAG "aconfig_cpp_codegen" #define ALOGI(msg, ...) \ #define ALOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__) __android_log_print(ANDROID_LOG_INFO, "AconfigTestMission1", (msg), __VA_ARGS__) {{ -endif }} {{ endif }} {{ endif }} {{ if readwrite- }} {{ if readwrite- }} Loading Loading @@ -66,8 +66,68 @@ namespace {cpp_namespace} \{ class flag_provider : public flag_provider_interface \{ class flag_provider : public flag_provider_interface \{ public: public: {{ -for item in class_elements }} {{ if allow_instrumentation- }} {{ if readwrite- }} flag_provider() {{ if readwrite- }} : cache_({readwrite_count}, -1) , boolean_start_index_() {{ -else- }} : boolean_start_index_() {{ -endif }} , flag_value_file_(nullptr) , read_from_new_storage_(false) , use_new_storage_value(false) \{ struct stat buffer; if (stat("/metadata/aconfig_test_missions/mission_1", &buffer) == 0) \{ read_from_new_storage_ = true; } else \{ return; } auto package_map_file = aconfig_storage::get_mapped_file( "{container}", aconfig_storage::StorageFileType::package_map); if (!package_map_file.ok()) \{ ALOGI("error: failed to get package map file: %s", package_map_file.error().c_str()); return; } auto context = aconfig_storage::get_package_read_context( **package_map_file, "{package}"); if (!context.ok()) \{ ALOGI("error: failed to get package read context: %s", context.error().c_str()); return; } // cache package boolean flag start index boolean_start_index_ = context->boolean_start_index; // unmap package map file and free memory delete *package_map_file; auto flag_value_file = aconfig_storage::get_mapped_file( "{container}", aconfig_storage::StorageFileType::flag_val); if (!flag_value_file.ok()) \{ ALOGI("error: failed to get flag value file: %s", flag_value_file.error().c_str()); return; } // cache flag value file flag_value_file_ = std::unique_ptr<aconfig_storage::MappedStorageFile>( *flag_value_file); use_new_storage_value = server_configurable_flags::GetServerConfigurableFlag( "aconfig_flags.core_experiments_team_internal", "com.android.providers.settings.use_new_storage_value", "false") == "true"; } {{ -endif }} {{ -endif }} {{ -for item in class_elements }} virtual bool {item.flag_name}() override \{ virtual bool {item.flag_name}() override \{ {{ -if item.readwrite }} {{ -if item.readwrite }} if (cache_[{item.readwrite_idx}] == -1) \{ if (cache_[{item.readwrite_idx}] == -1) \{ Loading @@ -76,6 +136,39 @@ namespace {cpp_namespace} \{ "{item.device_config_flag}", "{item.device_config_flag}", "{item.default_value}") == "true"; "{item.default_value}") == "true"; } } {{ if allow_instrumentation- }} if (read_from_new_storage_) \{ if (!flag_value_file_) \{ ALOGI("error: failed to get flag {item.flag_name}: flag value file is null"); return cache_[{item.readwrite_idx}]; } auto value = aconfig_storage::get_boolean_flag_value( *flag_value_file_, boolean_start_index_ + {item.flag_offset}); if (!value.ok()) \{ ALOGI("error: failed to read flag value: %s", value.error().c_str()); return cache_[{item.readwrite_idx}]; } bool expected_value = cache_[{item.readwrite_idx}]; if (*value != expected_value) \{ ALOGI("error: {item.flag_name} value mismatch, new storage value is %s, old storage value is %s", *value ? "true" : "false", expected_value ? "true" : "false"); } if (use_new_storage_value) \{ return *value; } else \{ return expected_value; } } {{ -endif }} return cache_[{item.readwrite_idx}]; return cache_[{item.readwrite_idx}]; {{ -else }} {{ -else }} {{ -if item.is_fixed_read_only }} {{ -if item.is_fixed_read_only }} Loading @@ -86,12 +179,21 @@ namespace {cpp_namespace} \{ {{ -endif }} {{ -endif }} } } {{ -endfor }} {{ -endfor }} {{ if readwrite- }} {{ if readwrite- }} private: private: std::vector<int8_t> cache_ = std::vector<int8_t>({readwrite_count}, -1); std::vector<int8_t> cache_ = std::vector<int8_t>({readwrite_count}, -1); {{ if allow_instrumentation- }} uint32_t boolean_start_index_; std::unique_ptr<aconfig_storage::MappedStorageFile> flag_value_file_; bool read_from_new_storage_; bool use_new_storage_value; {{ -endif }} {{ -endif }} {{ -endif }} }; }; {{ -endif }} {{ -endif }} Loading @@ -107,62 +209,6 @@ bool {header}_{item.flag_name}() \{ {{ -if item.readwrite }} {{ -if item.readwrite }} return {cpp_namespace}::{item.flag_name}(); return {cpp_namespace}::{item.flag_name}(); {{ -else }} {{ -else }} {{ if allow_instrumentation }} auto result = {{ if item.is_fixed_read_only }} {package_macro}_{item.flag_macro} {{ else }} {item.default_value} {{ endif }}; struct stat buffer; if (stat("/metadata/aconfig_test_missions/mission_1", &buffer) != 0) \{ return result; } auto package_map_file = aconfig_storage::get_mapped_file( "{item.container}", aconfig_storage::StorageFileType::package_map); if (!package_map_file.ok()) \{ ALOGI("error: failed to get package map file: %s", package_map_file.error().c_str()); return result; } auto package_read_context = aconfig_storage::get_package_read_context( **package_map_file, "{package}"); if (!package_read_context.ok()) \{ ALOGI("error: failed to get package read context: %s", package_map_file.error().c_str()); return result; } delete *package_map_file; auto flag_val_map = aconfig_storage::get_mapped_file( "{item.container}", aconfig_storage::StorageFileType::flag_val); if (!flag_val_map.ok()) \{ ALOGI("error: failed to get flag val map: %s", package_map_file.error().c_str()); return result; } auto value = aconfig_storage::get_boolean_flag_value( **flag_val_map, package_read_context->boolean_start_index + {item.flag_offset}); if (!value.ok()) \{ ALOGI("error: failed to get flag val: %s", package_map_file.error().c_str()); return result; } delete *flag_val_map; if (*value != result) \{ ALOGI("error: new storage value '%d' does not match current value '%d'", *value, result); } else \{ ALOGI("success: new storage value was '%d, legacy storage was '%d'", *value, result); } return result; {{ else }} {{ -if item.is_fixed_read_only }} {{ -if item.is_fixed_read_only }} return {package_macro}_{item.flag_macro}; return {package_macro}_{item.flag_macro}; {{ -else }} {{ -else }} Loading @@ -170,7 +216,6 @@ bool {header}_{item.flag_name}() \{ {{ -endif }} {{ -endif }} {{ -endif }} {{ -endif }} {{ -endif }} {{ -endif }} {{ -endif }} } } {{ -if is_test_mode }} {{ -if is_test_mode }} Loading @@ -185,5 +230,3 @@ void {header}_reset_flags() \{ {cpp_namespace}::reset_flags(); {cpp_namespace}::reset_flags(); } } {{ -endif }} {{ -endif }}