diff --git a/tools/aconfig/Android.bp b/tools/aconfig/Android.bp index 82bfa7ea7a..05fbad1d96 100644 --- a/tools/aconfig/Android.bp +++ b/tools/aconfig/Android.bp @@ -174,6 +174,12 @@ cc_aconfig_library { mode: "test", } +cc_aconfig_library { + name: "aconfig_test_cpp_library_exported_variant", + aconfig_declarations: "aconfig.test.flags", + mode: "exported", +} + cc_test { name: "aconfig.test.cpp", srcs: [ @@ -204,6 +210,21 @@ cc_test { test_suites: ["general-tests"], } +cc_test { + name: "aconfig.test.cpp.exported_mode", + srcs: [ + "tests/aconfig_exported_mode_test.cpp", + ], + static_libs: [ + "aconfig_test_cpp_library_exported_variant", + "libgmock", + ], + shared_libs: [ + "server_configurable_flags", + ], + test_suites: ["general-tests"], +} + rust_aconfig_library { name: "libaconfig_test_rust_library", crate_name: "aconfig_test_rust_library", diff --git a/tools/aconfig/src/codegen/cpp.rs b/tools/aconfig/src/codegen/cpp.rs index 568302d027..c420913644 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, } @@ -149,6 +153,10 @@ mod tests { #define COM_ANDROID_ACONFIG_TEST_ENABLED_FIXED_RO true #endif +#ifndef COM_ANDROID_ACONFIG_TEST_ENABLED_FIXED_RO_EXPORTED +#define COM_ANDROID_ACONFIG_TEST_ENABLED_FIXED_RO_EXPORTED true +#endif + #ifdef __cplusplus #include @@ -169,6 +177,8 @@ public: virtual bool enabled_fixed_ro() = 0; + virtual bool enabled_fixed_ro_exported() = 0; + virtual bool enabled_ro() = 0; virtual bool enabled_ro_exported() = 0; @@ -198,6 +208,10 @@ inline bool enabled_fixed_ro() { return COM_ANDROID_ACONFIG_TEST_ENABLED_FIXED_RO; } +inline bool enabled_fixed_ro_exported() { + return COM_ANDROID_ACONFIG_TEST_ENABLED_FIXED_RO_EXPORTED; +} + inline bool enabled_ro() { return true; } @@ -225,6 +239,8 @@ bool com_android_aconfig_test_disabled_rw_in_other_namespace(); bool com_android_aconfig_test_enabled_fixed_ro(); +bool com_android_aconfig_test_enabled_fixed_ro_exported(); + bool com_android_aconfig_test_enabled_ro(); bool com_android_aconfig_test_enabled_ro_exported(); @@ -270,6 +286,10 @@ public: virtual void enabled_fixed_ro(bool val) = 0; + virtual bool enabled_fixed_ro_exported() = 0; + + virtual void enabled_fixed_ro_exported(bool val) = 0; + virtual bool enabled_ro() = 0; virtual void enabled_ro(bool val) = 0; @@ -327,6 +347,14 @@ inline void enabled_fixed_ro(bool val) { provider_->enabled_fixed_ro(val); } +inline bool enabled_fixed_ro_exported() { + return provider_->enabled_fixed_ro_exported(); +} + +inline void enabled_fixed_ro_exported(bool val) { + provider_->enabled_fixed_ro_exported(val); +} + inline bool enabled_ro() { return provider_->enabled_ro(); } @@ -380,6 +408,10 @@ bool com_android_aconfig_test_enabled_fixed_ro(); void set_com_android_aconfig_test_enabled_fixed_ro(bool val); +bool com_android_aconfig_test_enabled_fixed_ro_exported(); + +void set_com_android_aconfig_test_enabled_fixed_ro_exported(bool val); + bool com_android_aconfig_test_enabled_ro(); void set_com_android_aconfig_test_enabled_ro(bool val); @@ -400,6 +432,56 @@ void com_android_aconfig_test_reset_flags(); #endif +"#; + + const EXPORTED_EXPORTED_HEADER_EXPECTED: &str = r#" +#pragma once + +#ifdef __cplusplus + +#include + +namespace com::android::aconfig::test { + +class flag_provider_interface { +public: + virtual ~flag_provider_interface() = default; + + virtual bool disabled_rw_exported() = 0; + + virtual bool enabled_fixed_ro_exported() = 0; + + virtual bool enabled_ro_exported() = 0; +}; + +extern std::unique_ptr provider_; + +inline bool disabled_rw_exported() { + return provider_->disabled_rw_exported(); +} + +inline bool enabled_fixed_ro_exported() { + return provider_->enabled_fixed_ro_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_fixed_ro_exported(); + +bool com_android_aconfig_test_enabled_ro_exported(); + +#ifdef __cplusplus +} // extern "C" +#endif "#; const PROD_SOURCE_FILE_EXPECTED: &str = r#" @@ -450,6 +532,10 @@ namespace com::android::aconfig::test { return COM_ANDROID_ACONFIG_TEST_ENABLED_FIXED_RO; } + virtual bool enabled_fixed_ro_exported() override { + return COM_ANDROID_ACONFIG_TEST_ENABLED_FIXED_RO_EXPORTED; + } + virtual bool enabled_ro() override { return true; } @@ -496,6 +582,10 @@ bool com_android_aconfig_test_enabled_fixed_ro() { return COM_ANDROID_ACONFIG_TEST_ENABLED_FIXED_RO; } +bool com_android_aconfig_test_enabled_fixed_ro_exported() { + return COM_ANDROID_ACONFIG_TEST_ENABLED_FIXED_RO_EXPORTED; +} + bool com_android_aconfig_test_enabled_ro() { return true; } @@ -601,6 +691,19 @@ namespace com::android::aconfig::test { overrides_["enabled_fixed_ro"] = val; } + virtual bool enabled_fixed_ro_exported() override { + auto it = overrides_.find("enabled_fixed_ro_exported"); + if (it != overrides_.end()) { + return it->second; + } else { + return true; + } + } + + virtual void enabled_fixed_ro_exported(bool val) override { + overrides_["enabled_fixed_ro_exported"] = val; + } + virtual bool enabled_ro() override { auto it = overrides_.find("enabled_ro"); if (it != overrides_.end()) { @@ -697,6 +800,13 @@ void set_com_android_aconfig_test_enabled_fixed_ro(bool val) { com::android::aconfig::test::enabled_fixed_ro(val); } +bool com_android_aconfig_test_enabled_fixed_ro_exported() { + return com::android::aconfig::test::enabled_fixed_ro_exported(); +} + +void set_com_android_aconfig_test_enabled_fixed_ro_exported(bool val) { + com::android::aconfig::test::enabled_fixed_ro_exported(val); +} bool com_android_aconfig_test_enabled_ro() { return com::android::aconfig::test::enabled_ro(); @@ -731,6 +841,68 @@ void com_android_aconfig_test_reset_flags() { com::android::aconfig::test::reset_flags(); } +"#; + + const EXPORTED_SOURCE_FILE_EXPECTED: &str = r#" +#include "com_android_aconfig_test.h" +#include +#include + +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_fixed_ro_exported() override { + if (cache_[1] == -1) { + cache_[1] = server_configurable_flags::GetServerConfigurableFlag( + "aconfig_flags.aconfig_test", + "com.android.aconfig.test.enabled_fixed_ro_exported", + "false") == "true"; + } + return cache_[1]; + } + + virtual bool enabled_ro_exported() override { + if (cache_[2] == -1) { + cache_[2] = server_configurable_flags::GetServerConfigurableFlag( + "aconfig_flags.aconfig_test", + "com.android.aconfig.test.enabled_ro_exported", + "false") == "true"; + } + return cache_[2]; + } + + private: + std::vector cache_ = std::vector(3, -1); + }; + + std::unique_ptr provider_ = + std::make_unique(); +} + +bool com_android_aconfig_test_disabled_rw_exported() { + return com::android::aconfig::test::disabled_rw_exported(); +} + +bool com_android_aconfig_test_enabled_fixed_ro_exported() { + return com::android::aconfig::test::enabled_fixed_ro_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#" @@ -854,12 +1026,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( @@ -911,6 +1082,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(); diff --git a/tools/aconfig/src/codegen/java.rs b/tools/aconfig/src/codegen/java.rs index 1d5dabf9f6..f874b344d7 100644 --- a/tools/aconfig/src/codegen/java.rs +++ b/tools/aconfig/src/codegen/java.rs @@ -202,6 +202,9 @@ mod tests { boolean enabledFixedRo(); @com.android.aconfig.annotations.AssumeTrueForR8 @UnsupportedAppUsage + boolean enabledFixedRoExported(); + @com.android.aconfig.annotations.AssumeTrueForR8 + @UnsupportedAppUsage boolean enabledRo(); @com.android.aconfig.annotations.AssumeTrueForR8 @UnsupportedAppUsage @@ -228,6 +231,8 @@ mod tests { /** @hide */ public static final String FLAG_ENABLED_FIXED_RO = "com.android.aconfig.test.enabled_fixed_ro"; /** @hide */ + public static final String FLAG_ENABLED_FIXED_RO_EXPORTED = "com.android.aconfig.test.enabled_fixed_ro_exported"; + /** @hide */ public static final String FLAG_ENABLED_RO = "com.android.aconfig.test.enabled_ro"; /** @hide */ public static final String FLAG_ENABLED_RO_EXPORTED = "com.android.aconfig.test.enabled_ro_exported"; @@ -258,6 +263,11 @@ mod tests { } @com.android.aconfig.annotations.AssumeTrueForR8 @UnsupportedAppUsage + public static boolean enabledFixedRoExported() { + return FEATURE_FLAGS.enabledFixedRoExported(); + } + @com.android.aconfig.annotations.AssumeTrueForR8 + @UnsupportedAppUsage public static boolean enabledRo() { return FEATURE_FLAGS.enabledRo(); } @@ -310,6 +320,11 @@ mod tests { } @Override @UnsupportedAppUsage + public boolean enabledFixedRoExported() { + return getValue(Flags.FLAG_ENABLED_FIXED_RO_EXPORTED); + } + @Override + @UnsupportedAppUsage public boolean enabledRo() { return getValue(Flags.FLAG_ENABLED_RO); } @@ -348,6 +363,7 @@ mod tests { Map.entry(Flags.FLAG_DISABLED_RW_EXPORTED, false), Map.entry(Flags.FLAG_DISABLED_RW_IN_OTHER_NAMESPACE, false), Map.entry(Flags.FLAG_ENABLED_FIXED_RO, false), + Map.entry(Flags.FLAG_ENABLED_FIXED_RO_EXPORTED, false), Map.entry(Flags.FLAG_ENABLED_RO, false), Map.entry(Flags.FLAG_ENABLED_RO_EXPORTED, false), Map.entry(Flags.FLAG_ENABLED_RW, false) @@ -463,6 +479,11 @@ mod tests { } @Override @UnsupportedAppUsage + public boolean enabledFixedRoExported() { + return true; + } + @Override + @UnsupportedAppUsage public boolean enabledRo() { return true; } @@ -528,6 +549,8 @@ mod tests { /** @hide */ public static final String FLAG_DISABLED_RW_EXPORTED = "com.android.aconfig.test.disabled_rw_exported"; /** @hide */ + public static final String FLAG_ENABLED_FIXED_RO_EXPORTED = "com.android.aconfig.test.enabled_fixed_ro_exported"; + /** @hide */ public static final String FLAG_ENABLED_RO_EXPORTED = "com.android.aconfig.test.enabled_ro_exported"; @UnsupportedAppUsage @@ -535,6 +558,10 @@ mod tests { return FEATURE_FLAGS.disabledRwExported(); } @UnsupportedAppUsage + public static boolean enabledFixedRoExported() { + return FEATURE_FLAGS.enabledFixedRoExported(); + } + @UnsupportedAppUsage public static boolean enabledRoExported() { return FEATURE_FLAGS.enabledRoExported(); } @@ -551,6 +578,8 @@ mod tests { @UnsupportedAppUsage boolean disabledRwExported(); @UnsupportedAppUsage + boolean enabledFixedRoExported(); + @UnsupportedAppUsage boolean enabledRoExported(); } "#; @@ -566,6 +595,7 @@ mod tests { private static boolean aconfig_test_is_cached = false; private static boolean other_namespace_is_cached = false; private static boolean disabledRwExported = false; + private static boolean enabledFixedRoExported = false; private static boolean enabledRoExported = false; @@ -574,6 +604,8 @@ mod tests { Properties properties = DeviceConfig.getProperties("aconfig_test"); disabledRwExported = properties.getBoolean("com.android.aconfig.test.disabled_rw_exported", false); + enabledFixedRoExported = + properties.getBoolean("com.android.aconfig.test.enabled_fixed_ro_exported", false); enabledRoExported = properties.getBoolean("com.android.aconfig.test.enabled_ro_exported", false); } catch (NullPointerException e) { @@ -614,6 +646,15 @@ mod tests { return disabledRwExported; } + @Override + @UnsupportedAppUsage + public boolean enabledFixedRoExported() { + if (!aconfig_test_is_cached) { + load_overrides_aconfig_test(); + } + return enabledFixedRoExported; + } + @Override @UnsupportedAppUsage public boolean enabledRoExported() { @@ -642,6 +683,11 @@ mod tests { } @Override @UnsupportedAppUsage + public boolean enabledFixedRoExported() { + return getValue(Flags.FLAG_ENABLED_FIXED_RO_EXPORTED); + } + @Override + @UnsupportedAppUsage public boolean enabledRoExported() { return getValue(Flags.FLAG_ENABLED_RO_EXPORTED); } @@ -666,6 +712,7 @@ mod tests { private Map mFlagMap = new HashMap<>( Map.ofEntries( Map.entry(Flags.FLAG_DISABLED_RW_EXPORTED, false), + Map.entry(Flags.FLAG_ENABLED_FIXED_RO_EXPORTED, false), Map.entry(Flags.FLAG_ENABLED_RO_EXPORTED, false) ) ); @@ -759,6 +806,12 @@ mod tests { } @Override @UnsupportedAppUsage + public boolean enabledFixedRoExported() { + throw new UnsupportedOperationException( + "Method is not implemented."); + } + @Override + @UnsupportedAppUsage public boolean enabledRo() { throw new UnsupportedOperationException( "Method is not implemented."); diff --git a/tools/aconfig/src/codegen/rust.rs b/tools/aconfig/src/codegen/rust.rs index 7aafddbea9..7c49c5055b 100644 --- a/tools/aconfig/src/codegen/rust.rs +++ b/tools/aconfig/src/codegen/rust.rs @@ -153,6 +153,11 @@ impl FlagProvider { true } + /// query flag enabled_fixed_ro_exported + pub fn enabled_fixed_ro_exported(&self) -> bool { + true + } + /// query flag enabled_ro pub fn enabled_ro(&self) -> bool { true @@ -202,6 +207,12 @@ pub fn enabled_fixed_ro() -> bool { true } +/// query flag enabled_fixed_ro_exported +#[inline(always)] +pub fn enabled_fixed_ro_exported() -> bool { + true +} + /// query flag enabled_ro #[inline(always)] pub fn enabled_ro() -> bool { @@ -302,6 +313,18 @@ impl FlagProvider { self.overrides.insert("enabled_fixed_ro", val); } + /// query flag enabled_fixed_ro_exported + pub fn enabled_fixed_ro_exported(&self) -> bool { + self.overrides.get("enabled_fixed_ro_exported").copied().unwrap_or( + true + ) + } + + /// set flag enabled_fixed_ro_exported + pub fn set_enabled_fixed_ro_exported(&mut self, val: bool) { + self.overrides.insert("enabled_fixed_ro_exported", val); + } + /// query flag enabled_ro pub fn enabled_ro(&self) -> bool { self.overrides.get("enabled_ro").copied().unwrap_or( @@ -412,6 +435,18 @@ pub fn set_enabled_fixed_ro(val: bool) { PROVIDER.lock().unwrap().set_enabled_fixed_ro(val); } +/// query flag enabled_fixed_ro_exported +#[inline(always)] +pub fn enabled_fixed_ro_exported() -> bool { + PROVIDER.lock().unwrap().enabled_fixed_ro_exported() +} + +/// set flag enabled_fixed_ro_exported +#[inline(always)] +pub fn set_enabled_fixed_ro_exported(val: bool) { + PROVIDER.lock().unwrap().set_enabled_fixed_ro_exported(val); +} + /// query flag enabled_ro #[inline(always)] pub fn enabled_ro() -> bool { diff --git a/tools/aconfig/src/commands.rs b/tools/aconfig/src/commands.rs index 87905fda1b..38c9fde5a7 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 Result> { 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 { @@ -335,6 +335,30 @@ fn filter_parsed_flags( } } +pub fn modify_parsed_flags_based_on_mode( + parsed_flags: ProtoParsedFlags, + codegen_mode: CodegenMode, +) -> Vec { + 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::*; @@ -366,9 +390,9 @@ mod tests { assert_eq!(ProtoFlagState::ENABLED, enabled_ro.trace[2].state()); assert_eq!(ProtoFlagPermission::READ_ONLY, enabled_ro.trace[2].permission()); - assert_eq!(8, parsed_flags.parsed_flag.len()); + assert_eq!(9, parsed_flags.parsed_flag.len()); for pf in parsed_flags.parsed_flag.iter() { - if pf.name() == "enabled_fixed_ro" { + if pf.name().starts_with("enabled_fixed_ro") { continue; } let first = pf.trace.first().unwrap(); @@ -597,7 +621,13 @@ mod tests { let bytes = dump_parsed_flags(vec![input, input2], DumpFormat::Textproto, &[], true).unwrap(); let text = std::str::from_utf8(&bytes).unwrap(); - assert_eq!(crate::test::TEST_FLAGS_TEXTPROTO.trim(), text.trim()); + assert_eq!( + None, + crate::test::first_significant_code_diff( + crate::test::TEST_FLAGS_TEXTPROTO.trim(), + text.trim() + ) + ); } #[test] @@ -607,14 +637,14 @@ mod tests { let filtered_parsed_flags = filter_parsed_flags(parsed_flags.clone(), CodegenMode::Exported); - assert_eq!(2, filtered_parsed_flags.len()); + assert_eq!(3, filtered_parsed_flags.len()); let filtered_parsed_flags = filter_parsed_flags(parsed_flags.clone(), CodegenMode::Production); - assert_eq!(8, filtered_parsed_flags.len()); + assert_eq!(9, filtered_parsed_flags.len()); let filtered_parsed_flags = filter_parsed_flags(parsed_flags.clone(), CodegenMode::Test); - assert_eq!(8, filtered_parsed_flags.len()); + assert_eq!(9, filtered_parsed_flags.len()); } fn parse_test_flags_as_input() -> Input { @@ -624,4 +654,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!(3, 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/src/dump.rs b/tools/aconfig/src/dump.rs index f2b368774c..5ee751ec22 100644 --- a/tools/aconfig/src/dump.rs +++ b/tools/aconfig/src/dump.rs @@ -341,6 +341,7 @@ mod tests { "com.android.aconfig.test.disabled_rw_exported", "com.android.aconfig.test.disabled_rw_in_other_namespace", "com.android.aconfig.test.enabled_fixed_ro", + "com.android.aconfig.test.enabled_fixed_ro_exported", "com.android.aconfig.test.enabled_ro", "com.android.aconfig.test.enabled_ro_exported", "com.android.aconfig.test.enabled_rw", @@ -360,6 +361,7 @@ mod tests { "state:ENABLED", &[ "com.android.aconfig.test.enabled_fixed_ro", + "com.android.aconfig.test.enabled_fixed_ro_exported", "com.android.aconfig.test.enabled_ro", "com.android.aconfig.test.enabled_ro_exported", "com.android.aconfig.test.enabled_rw", @@ -370,6 +372,7 @@ mod tests { &[ "com.android.aconfig.test.disabled_ro", "com.android.aconfig.test.enabled_fixed_ro", + "com.android.aconfig.test.enabled_fixed_ro_exported", "com.android.aconfig.test.enabled_ro", "com.android.aconfig.test.enabled_ro_exported", ] @@ -377,12 +380,16 @@ mod tests { // trace: not supported yet assert_create_filter_predicate!( "is_fixed_read_only:true", - &["com.android.aconfig.test.enabled_fixed_ro"] + &[ + "com.android.aconfig.test.enabled_fixed_ro", + "com.android.aconfig.test.enabled_fixed_ro_exported", + ] ); assert_create_filter_predicate!( "is_exported:true", &[ "com.android.aconfig.test.disabled_rw_exported", + "com.android.aconfig.test.enabled_fixed_ro_exported", "com.android.aconfig.test.enabled_ro_exported", ] ); @@ -394,6 +401,7 @@ mod tests { "com.android.aconfig.test.disabled_rw_exported", "com.android.aconfig.test.disabled_rw_in_other_namespace", "com.android.aconfig.test.enabled_fixed_ro", + "com.android.aconfig.test.enabled_fixed_ro_exported", "com.android.aconfig.test.enabled_ro", "com.android.aconfig.test.enabled_ro_exported", "com.android.aconfig.test.enabled_rw", @@ -406,6 +414,7 @@ mod tests { "permission:READ_ONLY+state:ENABLED", &[ "com.android.aconfig.test.enabled_fixed_ro", + "com.android.aconfig.test.enabled_fixed_ro_exported", "com.android.aconfig.test.enabled_ro", "com.android.aconfig.test.enabled_ro_exported", ] diff --git a/tools/aconfig/src/test.rs b/tools/aconfig/src/test.rs index 309cb28ceb..cbb95b8ef0 100644 --- a/tools/aconfig/src/test.rs +++ b/tools/aconfig/src/test.rs @@ -143,6 +143,31 @@ parsed_flag { purpose: PURPOSE_UNSPECIFIED } } +parsed_flag { + package: "com.android.aconfig.test" + name: "enabled_fixed_ro_exported" + namespace: "aconfig_test" + description: "This flag is fixed ENABLED + READ_ONLY and exported" + bug: "111" + state: ENABLED + permission: READ_ONLY + trace { + source: "tests/test.aconfig" + state: DISABLED + permission: READ_ONLY + } + trace { + source: "tests/first.values" + state: ENABLED + permission: READ_ONLY + } + is_fixed_read_only: true + is_exported: true + container: "system" + metadata { + purpose: PURPOSE_UNSPECIFIED + } +} parsed_flag { package: "com.android.aconfig.test" name: "enabled_ro" 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 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 -{{ -endif }} - -{{ if for_test- }} +{{ endif }} +{{ if is_test_mode }} #include #include {{ -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 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 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(); } diff --git a/tools/aconfig/tests/aconfig_exported_mode_test.cpp b/tools/aconfig/tests/aconfig_exported_mode_test.cpp new file mode 100644 index 0000000000..d6eab4336f --- /dev/null +++ b/tools/aconfig/tests/aconfig_exported_mode_test.cpp @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "com_android_aconfig_test.h" +#include "gtest/gtest.h" + +using namespace com::android::aconfig::test; + +TEST(AconfigTest, TestDisabledRwExportedFlag) { + ASSERT_FALSE(com_android_aconfig_test_disabled_rw_exported()); + ASSERT_FALSE(provider_->disabled_rw_exported()); + ASSERT_FALSE(disabled_rw_exported()); +} + +TEST(AconfigTest, TestEnabledFixedRoExportedFlag) { + // TODO: change to assertTrue(enabledFixedRoExported()) when the build supports reading tests/*.values + ASSERT_FALSE(com_android_aconfig_test_enabled_fixed_ro_exported()); + ASSERT_FALSE(provider_->enabled_fixed_ro_exported()); + ASSERT_FALSE(enabled_fixed_ro_exported()); +} + +TEST(AconfigTest, TestEnabledRoExportedFlag) { + // TODO: change to assertTrue(enabledRoExported()) when the build supports reading tests/*.values + ASSERT_FALSE(com_android_aconfig_test_enabled_ro_exported()); + ASSERT_FALSE(provider_->enabled_ro_exported()); + ASSERT_FALSE(enabled_ro_exported()); +} + +int main(int argc, char** argv) { + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} \ No newline at end of file diff --git a/tools/aconfig/tests/first.values b/tools/aconfig/tests/first.values index 731ce8483f..2efb4632d4 100644 --- a/tools/aconfig/tests/first.values +++ b/tools/aconfig/tests/first.values @@ -40,3 +40,9 @@ flag_value { state: DISABLED permission: READ_WRITE } +flag_value { + package: "com.android.aconfig.test" + name: "enabled_fixed_ro_exported" + state: ENABLED + permission: READ_ONLY +} diff --git a/tools/aconfig/tests/test.aconfig b/tools/aconfig/tests/test.aconfig index 014bced239..c11508aabc 100644 --- a/tools/aconfig/tests/test.aconfig +++ b/tools/aconfig/tests/test.aconfig @@ -78,3 +78,12 @@ flag { bug: "111" is_exported: true } + +flag { + name: "enabled_fixed_ro_exported" + namespace: "aconfig_test" + description: "This flag is fixed ENABLED + READ_ONLY and exported" + bug: "111" + is_fixed_read_only: true + is_exported: true +} \ No newline at end of file