summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Zhi Dou <zhidou@google.com> 2023-12-14 21:17:13 +0000
committer Zhi Dou <zhidou@google.com> 2023-12-19 16:35:13 +0000
commitc1d0a14b69602ca3c6cc124f859540c3e8315e7d (patch)
tree42830d88b5b6b1161d5de08976ea9cfd666b861a
parent4dc569ae493c0fc7a5ad7034c81064896d692007 (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.rs121
-rw-r--r--tools/aconfig/src/commands.rs54
-rw-r--r--tools/aconfig/templates/cpp_exported_header.template22
-rw-r--r--tools/aconfig/templates/cpp_source_file.template31
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();
}