aconfig: support api behind a macro flag in c/cpp

Bug: b/299673148
Test: atest aconfig.test
Change-Id: I54011de7b8eb52c97a84a93aa1cb955a9eb02706
diff --git a/tools/aconfig/src/codegen_cpp.rs b/tools/aconfig/src/codegen_cpp.rs
index cf0abb9..aeb57a3 100644
--- a/tools/aconfig/src/codegen_cpp.rs
+++ b/tools/aconfig/src/codegen_cpp.rs
@@ -34,13 +34,17 @@
     let class_elements: Vec<ClassElement> =
         parsed_flags_iter.map(|pf| create_class_element(package, pf)).collect();
     let readwrite = class_elements.iter().any(|item| item.readwrite);
+    let has_fixed_read_only = class_elements.iter().any(|item| item.is_fixed_read_only);
     let header = package.replace('.', "_");
+    let package_macro = header.to_uppercase();
     let cpp_namespace = package.replace('.', "::");
     ensure!(codegen::is_valid_name_ident(&header));
     let context = Context {
         header: &header,
+        package_macro: &package_macro,
         cpp_namespace: &cpp_namespace,
         package,
+        has_fixed_read_only,
         readwrite,
         for_test: codegen_mode == CodegenMode::Test,
         class_elements,
@@ -79,8 +83,10 @@
 #[derive(Serialize)]
 pub struct Context<'a> {
     pub header: &'a str,
+    pub package_macro: &'a str,
     pub cpp_namespace: &'a str,
     pub package: &'a str,
+    pub has_fixed_read_only: bool,
     pub readwrite: bool,
     pub for_test: bool,
     pub class_elements: Vec<ClassElement>,
@@ -89,8 +95,10 @@
 #[derive(Serialize)]
 pub struct ClassElement {
     pub readwrite: bool,
+    pub is_fixed_read_only: bool,
     pub default_value: String,
     pub flag_name: String,
+    pub flag_macro: String,
     pub device_config_namespace: String,
     pub device_config_flag: String,
 }
@@ -98,12 +106,14 @@
 fn create_class_element(package: &str, pf: &ProtoParsedFlag) -> ClassElement {
     ClassElement {
         readwrite: pf.permission() == ProtoFlagPermission::READ_WRITE,
+        is_fixed_read_only: pf.is_fixed_read_only(),
         default_value: if pf.state() == ProtoFlagState::ENABLED {
             "true".to_string()
         } else {
             "false".to_string()
         },
         flag_name: pf.name().to_string(),
+        flag_macro: pf.name().to_uppercase(),
         device_config_namespace: pf.namespace().to_string(),
         device_config_flag: codegen::create_device_config_ident(package, pf.name())
             .expect("values checked at flag parse time"),
@@ -118,6 +128,14 @@
     const EXPORTED_PROD_HEADER_EXPECTED: &str = r#"
 #pragma once
 
+#ifndef COM_ANDROID_ACONFIG_TEST
+#define COM_ANDROID_ACONFIG_TEST(FLAG) COM_ANDROID_ACONFIG_TEST_##FLAG
+#endif
+
+#ifndef COM_ANDROID_ACONFIG_TEST_ENABLED_FIXED_RO
+#define COM_ANDROID_ACONFIG_TEST_ENABLED_FIXED_RO true
+#endif
+
 #ifdef __cplusplus
 
 #include <memory>
@@ -149,7 +167,7 @@
 }
 
 inline bool enabled_fixed_ro() {
-    return true;
+    return COM_ANDROID_ACONFIG_TEST_ENABLED_FIXED_RO;
 }
 
 inline bool enabled_ro() {
@@ -319,7 +337,7 @@
             }
 
             virtual bool enabled_fixed_ro() override {
-                return true;
+                return COM_ANDROID_ACONFIG_TEST_ENABLED_FIXED_RO;
             }
 
             virtual bool enabled_ro() override {
@@ -348,7 +366,7 @@
 }
 
 bool com_android_aconfig_test_enabled_fixed_ro() {
-    return true;
+    return COM_ANDROID_ACONFIG_TEST_ENABLED_FIXED_RO;
 }
 
 bool com_android_aconfig_test_enabled_ro() {
diff --git a/tools/aconfig/templates/cpp_exported_header.template b/tools/aconfig/templates/cpp_exported_header.template
index 4d56dbc..6413699 100644
--- a/tools/aconfig/templates/cpp_exported_header.template
+++ b/tools/aconfig/templates/cpp_exported_header.template
@@ -1,9 +1,25 @@
 #pragma once
 
+{{ if not for_test- }}
+{{ if has_fixed_read_only- }}
+#ifndef {package_macro}
+#define {package_macro}(FLAG) {package_macro}_##FLAG
+#endif
+{{ for item in class_elements- }}
+{{ if item.is_fixed_read_only- }}
+#ifndef {package_macro}_{item.flag_macro}
+#define {package_macro}_{item.flag_macro} {item.default_value}
+#endif
+{{ endif }}
+{{ -endfor }}
+{{ -endif }}
+{{ -endif }}
+
 #ifdef __cplusplus
 
 #include <memory>
 
+
 namespace {cpp_namespace} \{
 
 class flag_provider_interface \{
@@ -15,7 +31,7 @@
     {{ if for_test }}
     virtual void {item.flag_name}(bool val) = 0;
     {{ -endif }}
-    {{ endfor }}
+    {{ -endfor }}
 
     {{ if for_test }}
     virtual void reset_flags() \{}
@@ -29,10 +45,14 @@
     {{ if for_test }}
     return provider_->{item.flag_name}();
     {{ -else- }}
-    {{ if not item.readwrite- }}
-    return {item.default_value};
-    {{ -else- }}
+    {{ if item.readwrite- }}
     return provider_->{item.flag_name}();
+    {{ -else- }}
+    {{ if item.is_fixed_read_only }}
+    return {package_macro}_{item.flag_macro};
+    {{ -else- }}
+    return {item.default_value};
+    {{ -endif }}
     {{ -endif }}
     {{ -endif }}
 }
@@ -42,7 +62,7 @@
     provider_->{item.flag_name}(val);
 }
 {{ -endif }}
-{{ endfor }}
+{{ -endfor }}
 
 {{ if for_test }}
 inline void reset_flags() \{
@@ -61,7 +81,7 @@
 {{ if for_test }}
 void set_{header}_{item.flag_name}(bool val);
 {{ -endif }}
-{{ endfor - }}
+{{ -endfor }}
 
 {{ if for_test }}
 void {header}_reset_flags();
diff --git a/tools/aconfig/templates/cpp_source_file.template b/tools/aconfig/templates/cpp_source_file.template
index 5b71b31..0f1b845 100644
--- a/tools/aconfig/templates/cpp_source_file.template
+++ b/tools/aconfig/templates/cpp_source_file.template
@@ -58,7 +58,11 @@
                 "{item.device_config_flag}",
                 "{item.default_value}") == "true";
             {{ -else- }}
-                return {item.default_value};
+            {{ if item.is_fixed_read_only }}
+            return {package_macro}_{item.flag_macro};
+            {{ -else- }}
+            return {item.default_value};
+            {{ -endif }}
             {{ -endif }}
         }
         {{ endfor }}
@@ -79,10 +83,14 @@
     {{ if for_test }}
     return {cpp_namespace}::{item.flag_name}();
     {{ -else- }}
-    {{ if not item.readwrite- }}
-    return {item.default_value};
-    {{ -else- }}
+    {{ if item.readwrite- }}
     return {cpp_namespace}::{item.flag_name}();
+    {{ -else- }}
+    {{ if item.is_fixed_read_only }}
+    return {package_macro}_{item.flag_macro};
+    {{ -else- }}
+    return {item.default_value};
+    {{ -endif }}
     {{ -endif }}
     {{ -endif }}
 }