diff options
| author | 2023-12-14 21:17:13 +0000 | |
|---|---|---|
| committer | 2023-12-19 16:35:13 +0000 | |
| commit | c1d0a14b69602ca3c6cc124f859540c3e8315e7d (patch) | |
| tree | 42830d88b5b6b1161d5de08976ea9cfd666b861a | |
| parent | 4dc569ae493c0fc7a5ad7034c81064896d692007 (diff) | |
aconfig: add exported mode in c/c++ codegen
This commit adds exported mode to c/c++ codegen.
When the codegen mode is exported
1. only flags with exported: true will be generated
2. the generated getter should be in a read_write format and with
default value as false, regardless the original permission and state
of the flag
This change moves process parsed_flags funciton into codegen crate. The
process function is used to process parsed_flags based on the codegen
mode.
The template has also modified to keep readability.
Bug: 316357680
Test: atest aconfig.test aconfig.test.cpp aconfig.test.cpp.test_mode
Change-Id: I511e05ab93b07a04236055d956d1926f4ed89f36
| -rw-r--r-- | tools/aconfig/src/codegen/cpp.rs | 121 | ||||
| -rw-r--r-- | tools/aconfig/src/commands.rs | 54 | ||||
| -rw-r--r-- | tools/aconfig/templates/cpp_exported_header.template | 22 | ||||
| -rw-r--r-- | tools/aconfig/templates/cpp_source_file.template | 31 |
4 files changed, 202 insertions, 26 deletions
diff --git a/tools/aconfig/src/codegen/cpp.rs b/tools/aconfig/src/codegen/cpp.rs index 568302d027..280d3ff3b8 100644 --- a/tools/aconfig/src/codegen/cpp.rs +++ b/tools/aconfig/src/codegen/cpp.rs @@ -49,7 +49,9 @@ where has_fixed_read_only, readwrite, readwrite_count, - for_test: codegen_mode == CodegenMode::Test, + is_test_mode: codegen_mode == CodegenMode::Test, + is_prod_mode: codegen_mode == CodegenMode::Production, + is_exported_mode: codegen_mode == CodegenMode::Exported, class_elements, }; @@ -92,7 +94,9 @@ pub struct Context<'a> { pub has_fixed_read_only: bool, pub readwrite: bool, pub readwrite_count: i32, - pub for_test: bool, + pub is_test_mode: bool, + pub is_prod_mode: bool, + pub is_exported_mode: bool, pub class_elements: Vec<ClassElement>, } @@ -402,6 +406,48 @@ void com_android_aconfig_test_reset_flags(); "#; + const EXPORTED_EXPORTED_HEADER_EXPECTED: &str = r#" +#pragma once + +#ifdef __cplusplus + +#include <memory> + +namespace com::android::aconfig::test { + +class flag_provider_interface { +public: + virtual ~flag_provider_interface() = default; + + virtual bool disabled_rw_exported() = 0; + + virtual bool enabled_ro_exported() = 0; +}; + +extern std::unique_ptr<flag_provider_interface> provider_; + +inline bool disabled_rw_exported() { + return provider_->disabled_rw_exported(); +} + +inline bool enabled_ro_exported() { + return provider_->enabled_ro_exported(); +} + +} + +extern "C" { +#endif // __cplusplus + +bool com_android_aconfig_test_disabled_rw_exported(); + +bool com_android_aconfig_test_enabled_ro_exported(); + +#ifdef __cplusplus +} // extern "C" +#endif +"#; + const PROD_SOURCE_FILE_EXPECTED: &str = r#" #include "com_android_aconfig_test.h" #include <server_configurable_flags/get_flags.h> @@ -733,6 +779,55 @@ void com_android_aconfig_test_reset_flags() { "#; + const EXPORTED_SOURCE_FILE_EXPECTED: &str = r#" +#include "com_android_aconfig_test.h" +#include <server_configurable_flags/get_flags.h> +#include <vector> + +namespace com::android::aconfig::test { + + class flag_provider : public flag_provider_interface { + public: + virtual bool disabled_rw_exported() override { + if (cache_[0] == -1) { + cache_[0] = server_configurable_flags::GetServerConfigurableFlag( + "aconfig_flags.aconfig_test", + "com.android.aconfig.test.disabled_rw_exported", + "false") == "true"; + } + return cache_[0]; + } + + virtual bool enabled_ro_exported() override { + if (cache_[1] == -1) { + cache_[1] = server_configurable_flags::GetServerConfigurableFlag( + "aconfig_flags.aconfig_test", + "com.android.aconfig.test.enabled_ro_exported", + "false") == "true"; + } + return cache_[1]; + } + + + private: + std::vector<int8_t> cache_ = std::vector<int8_t>(2, -1); + }; + + std::unique_ptr<flag_provider_interface> provider_ = + std::make_unique<flag_provider>(); +} + +bool com_android_aconfig_test_disabled_rw_exported() { + return com::android::aconfig::test::disabled_rw_exported(); +} + +bool com_android_aconfig_test_enabled_ro_exported() { + return com::android::aconfig::test::enabled_ro_exported(); +} + + +"#; + const READ_ONLY_EXPORTED_PROD_HEADER_EXPECTED: &str = r#" #pragma once @@ -854,12 +949,11 @@ bool com_android_aconfig_test_enabled_ro() { expected_header: &str, expected_src: &str, ) { - let generated = generate_cpp_code( - crate::test::TEST_PACKAGE, - parsed_flags.parsed_flag.into_iter(), - mode, - ) - .unwrap(); + let modified_parsed_flags = + crate::commands::modify_parsed_flags_based_on_mode(parsed_flags, mode); + let generated = + generate_cpp_code(crate::test::TEST_PACKAGE, modified_parsed_flags.into_iter(), mode) + .unwrap(); let mut generated_files_map = HashMap::new(); for file in generated { generated_files_map.insert( @@ -912,6 +1006,17 @@ bool com_android_aconfig_test_enabled_ro() { } #[test] + fn test_generate_cpp_code_for_exported() { + let parsed_flags = crate::test::parse_test_flags(); + test_generate_cpp_code( + parsed_flags, + CodegenMode::Exported, + EXPORTED_EXPORTED_HEADER_EXPECTED, + EXPORTED_SOURCE_FILE_EXPECTED, + ); + } + + #[test] fn test_generate_cpp_code_for_read_only_prod() { let parsed_flags = crate::test::parse_read_only_test_flags(); test_generate_cpp_code( diff --git a/tools/aconfig/src/commands.rs b/tools/aconfig/src/commands.rs index 87905fda1b..262111249b 100644 --- a/tools/aconfig/src/commands.rs +++ b/tools/aconfig/src/commands.rs @@ -207,12 +207,12 @@ pub fn create_java_lib(mut input: Input, codegen_mode: CodegenMode) -> Result<Ve pub fn create_cpp_lib(mut input: Input, codegen_mode: CodegenMode) -> Result<Vec<OutputFile>> { let parsed_flags = input.try_parse_flags()?; - let filtered_parsed_flags = filter_parsed_flags(parsed_flags, codegen_mode); - let Some(package) = find_unique_package(&filtered_parsed_flags) else { + let modified_parsed_flags = modify_parsed_flags_based_on_mode(parsed_flags, codegen_mode); + let Some(package) = find_unique_package(&modified_parsed_flags) else { bail!("no parsed flags, or the parsed flags use different packages"); }; let package = package.to_string(); - generate_cpp_code(&package, filtered_parsed_flags.into_iter(), codegen_mode) + generate_cpp_code(&package, modified_parsed_flags.into_iter(), codegen_mode) } pub fn create_rust_lib(mut input: Input, codegen_mode: CodegenMode) -> Result<OutputFile> { @@ -335,6 +335,30 @@ fn filter_parsed_flags( } } +pub fn modify_parsed_flags_based_on_mode( + parsed_flags: ProtoParsedFlags, + codegen_mode: CodegenMode, +) -> Vec<ProtoParsedFlag> { + fn exported_mode_flag_modifier(mut parsed_flag: ProtoParsedFlag) -> ProtoParsedFlag { + parsed_flag.set_state(ProtoFlagState::DISABLED); + parsed_flag.set_permission(ProtoFlagPermission::READ_WRITE); + parsed_flag.set_is_fixed_read_only(false); + parsed_flag + } + + match codegen_mode { + CodegenMode::Exported => parsed_flags + .parsed_flag + .into_iter() + .filter(|pf| pf.is_exported()) + .map(exported_mode_flag_modifier) + .collect(), + CodegenMode::Production | CodegenMode::Test => { + parsed_flags.parsed_flag.into_iter().collect() + } + } +} + #[cfg(test)] mod tests { use super::*; @@ -624,4 +648,28 @@ mod tests { let reader = Box::new(cursor); Input { source: "test.data".to_string(), reader } } + + #[test] + fn test_modify_parsed_flags_based_on_mode_prod() { + let parsed_flags = crate::test::parse_test_flags(); + let p_parsed_flags = + modify_parsed_flags_based_on_mode(parsed_flags.clone(), CodegenMode::Production); + assert_eq!(parsed_flags.parsed_flag.len(), p_parsed_flags.len()); + for (i, item) in p_parsed_flags.iter().enumerate() { + assert!(parsed_flags.parsed_flag[i].eq(item)); + } + } + + #[test] + fn test_modify_parsed_flags_based_on_mode_exported() { + let parsed_flags = crate::test::parse_test_flags(); + let p_parsed_flags = modify_parsed_flags_based_on_mode(parsed_flags, CodegenMode::Exported); + assert_eq!(2, p_parsed_flags.len()); + for flag in p_parsed_flags.iter() { + assert_eq!(ProtoFlagState::DISABLED, flag.state()); + assert_eq!(ProtoFlagPermission::READ_WRITE, flag.permission()); + assert!(!flag.is_fixed_read_only()); + assert!(flag.is_exported()); + } + } } diff --git a/tools/aconfig/templates/cpp_exported_header.template b/tools/aconfig/templates/cpp_exported_header.template index 377295d873..8db9ec43f6 100644 --- a/tools/aconfig/templates/cpp_exported_header.template +++ b/tools/aconfig/templates/cpp_exported_header.template @@ -1,6 +1,6 @@ #pragma once -{{ if not for_test- }} +{{ if not is_test_mode- }} {{ if has_fixed_read_only- }} #ifndef {package_macro} #define {package_macro}(FLAG) {package_macro}_##FLAG @@ -29,12 +29,12 @@ public: {{ for item in class_elements}} virtual bool {item.flag_name}() = 0; - {{ if for_test- }} + {{ if is_test_mode }} virtual void {item.flag_name}(bool val) = 0; {{ -endif }} {{ -endfor }} - {{ if for_test }} + {{ if is_test_mode }} virtual void reset_flags() \{} {{ -endif }} }; @@ -43,9 +43,10 @@ extern std::unique_ptr<flag_provider_interface> provider_; {{ for item in class_elements}} inline bool {item.flag_name}() \{ - {{ if for_test- }} + {{ if is_test_mode }} return provider_->{item.flag_name}(); {{ -else- }} + {{ if is_prod_mode- }} {{ if item.readwrite- }} return provider_->{item.flag_name}(); {{ -else- }} @@ -55,17 +56,22 @@ inline bool {item.flag_name}() \{ return {item.default_value}; {{ -endif }} {{ -endif }} + {{ -else- }} + {{ if is_exported_mode- }} + return provider_->{item.flag_name}(); + {{ -endif }} + {{ -endif }} {{ -endif }} } -{{ if for_test- }} +{{ if is_test_mode }} inline void {item.flag_name}(bool val) \{ provider_->{item.flag_name}(val); } {{ -endif }} {{ -endfor }} -{{ if for_test- }} +{{ if is_test_mode }} inline void reset_flags() \{ return provider_->reset_flags(); } @@ -79,12 +85,12 @@ extern "C" \{ {{ for item in class_elements }} bool {header}_{item.flag_name}(); -{{ if for_test- }} +{{ if is_test_mode }} void set_{header}_{item.flag_name}(bool val); {{ -endif }} {{ -endfor }} -{{ if for_test- }} +{{ if is_test_mode }} void {header}_reset_flags(); {{ -endif }} diff --git a/tools/aconfig/templates/cpp_source_file.template b/tools/aconfig/templates/cpp_source_file.template index fbbfedc201..a10d7cb7d1 100644 --- a/tools/aconfig/templates/cpp_source_file.template +++ b/tools/aconfig/templates/cpp_source_file.template @@ -2,9 +2,8 @@ {{ if readwrite- }} #include <server_configurable_flags/get_flags.h> -{{ -endif }} - -{{ if for_test- }} +{{ endif }} +{{ if is_test_mode }} #include <unordered_map> #include <string> {{ -else- }} @@ -15,7 +14,7 @@ namespace {cpp_namespace} \{ -{{ if for_test- }} +{{ if is_test_mode }} class flag_provider : public flag_provider_interface \{ private: std::unordered_map<std::string, bool> overrides_; @@ -59,6 +58,7 @@ namespace {cpp_namespace} \{ {{ for item in class_elements }} virtual bool {item.flag_name}() override \{ + {{ if is_prod_mode- }} {{ if item.readwrite- }} if (cache_[{item.readwrite_idx}] == -1) \{ cache_[{item.readwrite_idx}] = server_configurable_flags::GetServerConfigurableFlag( @@ -74,6 +74,17 @@ namespace {cpp_namespace} \{ return {item.default_value}; {{ -endif }} {{ -endif }} + {{ -else- }} + {{ if is_exported_mode-}} + if (cache_[{item.readwrite_idx}] == -1) \{ + cache_[{item.readwrite_idx}] = server_configurable_flags::GetServerConfigurableFlag( + "aconfig_flags.{item.device_config_namespace}", + "{item.device_config_flag}", + "false") == "true"; + } + return cache_[{item.readwrite_idx}]; + {{ -endif }} + {{ -endif }} } {{ endfor }} {{ if readwrite- }} @@ -91,9 +102,10 @@ std::unique_ptr<flag_provider_interface> provider_ = {{ for item in class_elements }} bool {header}_{item.flag_name}() \{ - {{ if for_test- }} + {{ if is_test_mode }} return {cpp_namespace}::{item.flag_name}(); {{ -else- }} + {{ if is_prod_mode- }} {{ if item.readwrite- }} return {cpp_namespace}::{item.flag_name}(); {{ -else- }} @@ -103,17 +115,22 @@ bool {header}_{item.flag_name}() \{ return {item.default_value}; {{ -endif }} {{ -endif }} + {{ -else- }} + {{ if is_exported_mode- }} + return {cpp_namespace}::{item.flag_name}(); + {{ -endif }} + {{ -endif }} {{ -endif }} } -{{ if for_test- }} +{{ if is_test_mode }} void set_{header}_{item.flag_name}(bool val) \{ {cpp_namespace}::{item.flag_name}(val); } {{ -endif }} {{ endfor-}} -{{ if for_test }} +{{ if is_test_mode }} void {header}_reset_flags() \{ {cpp_namespace}::reset_flags(); } |