Loading tools/aconfig/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -58,6 +58,7 @@ rust_defaults { "libaconfig_protos", "libanyhow", "libclap", "libitertools", "libprotobuf", "libserde", "libserde_json", Loading tools/aconfig/Cargo.toml +1 −0 Original line number Diff line number Diff line Loading @@ -11,6 +11,7 @@ cargo = [] [dependencies] anyhow = "1.0.69" clap = { version = "4.1.8", features = ["derive"] } itertools = "0.10.5" paste = "1.0.11" protobuf = "3.2.0" serde = { version = "1.0.152", features = ["derive"] } Loading tools/aconfig/src/codegen_cpp.rs +73 −7 Original line number Diff line number Diff line Loading @@ -32,8 +32,9 @@ where I: Iterator<Item = &'a ProtoParsedFlag>, { let mut readwrite_count = 0; let class_elements: Vec<ClassElement> = parsed_flags_iter.map(|pf| create_class_element(package, pf, &mut readwrite_count)).collect(); let class_elements: Vec<ClassElement> = parsed_flags_iter .map(|pf| create_class_element(package, pf, &mut readwrite_count)) .collect(); let readwrite = readwrite_count > 0; let has_fixed_read_only = class_elements.iter().any(|item| item.is_fixed_read_only); let header = package.replace('.', "_"); Loading Loading @@ -110,7 +111,9 @@ pub struct ClassElement { fn create_class_element(package: &str, pf: &ProtoParsedFlag, rw_count: &mut i32) -> ClassElement { ClassElement { readwrite_idx: if pf.permission() == ProtoFlagPermission::READ_WRITE { let index = *rw_count; *rw_count += 1; index let index = *rw_count; *rw_count += 1; index } else { -1 }, Loading Loading @@ -162,6 +165,8 @@ public: virtual bool disabled_rw() = 0; virtual bool disabled_rw_2() = 0; virtual bool enabled_fixed_ro() = 0; virtual bool enabled_ro() = 0; Loading @@ -179,6 +184,10 @@ inline bool disabled_rw() { return provider_->disabled_rw(); } inline bool disabled_rw_2() { return provider_->disabled_rw_2(); } inline bool enabled_fixed_ro() { return COM_ANDROID_ACONFIG_TEST_ENABLED_FIXED_RO; } Loading @@ -200,6 +209,8 @@ bool com_android_aconfig_test_disabled_ro(); bool com_android_aconfig_test_disabled_rw(); bool com_android_aconfig_test_disabled_rw_2(); bool com_android_aconfig_test_enabled_fixed_ro(); bool com_android_aconfig_test_enabled_ro(); Loading Loading @@ -233,6 +244,10 @@ public: virtual void disabled_rw(bool val) = 0; virtual bool disabled_rw_2() = 0; virtual void disabled_rw_2(bool val) = 0; virtual bool enabled_fixed_ro() = 0; virtual void enabled_fixed_ro(bool val) = 0; Loading Loading @@ -266,6 +281,14 @@ inline void disabled_rw(bool val) { provider_->disabled_rw(val); } inline bool disabled_rw_2() { return provider_->disabled_rw_2(); } inline void disabled_rw_2(bool val) { provider_->disabled_rw_2(val); } inline bool enabled_fixed_ro() { return provider_->enabled_fixed_ro(); } Loading Loading @@ -307,6 +330,10 @@ bool com_android_aconfig_test_disabled_rw(); void set_com_android_aconfig_test_disabled_rw(bool val); bool com_android_aconfig_test_disabled_rw_2(); void set_com_android_aconfig_test_disabled_rw_2(bool val); bool com_android_aconfig_test_enabled_fixed_ro(); void set_com_android_aconfig_test_enabled_fixed_ro(bool val); Loading Loading @@ -352,6 +379,16 @@ namespace com::android::aconfig::test { return cache_[0]; } virtual bool disabled_rw_2() override { if (cache_[1] == -1) { cache_[1] = server_configurable_flags::GetServerConfigurableFlag( "aconfig_flags.other_namespace", "com.android.aconfig.test.disabled_rw_2", "false") == "true"; } return cache_[1]; } virtual bool enabled_fixed_ro() override { return COM_ANDROID_ACONFIG_TEST_ENABLED_FIXED_RO; } Loading @@ -361,18 +398,18 @@ namespace com::android::aconfig::test { } virtual bool enabled_rw() override { if (cache_[1] == -1) { cache_[1] = server_configurable_flags::GetServerConfigurableFlag( if (cache_[2] == -1) { cache_[2] = server_configurable_flags::GetServerConfigurableFlag( "aconfig_flags.aconfig_test", "com.android.aconfig.test.enabled_rw", "true") == "true"; } return cache_[1]; return cache_[2]; } }; std::vector<int8_t> cache_ = std::vector<int8_t>(2, -1); std::vector<int8_t> cache_ = std::vector<int8_t>(3, -1); std::unique_ptr<flag_provider_interface> provider_ = std::make_unique<flag_provider>(); Loading @@ -386,6 +423,10 @@ bool com_android_aconfig_test_disabled_rw() { return com::android::aconfig::test::disabled_rw(); } bool com_android_aconfig_test_disabled_rw_2() { return com::android::aconfig::test::disabled_rw_2(); } bool com_android_aconfig_test_enabled_fixed_ro() { return COM_ANDROID_ACONFIG_TEST_ENABLED_FIXED_RO; } Loading Loading @@ -446,6 +487,22 @@ namespace com::android::aconfig::test { overrides_["disabled_rw"] = val; } virtual bool disabled_rw_2() override { auto it = overrides_.find("disabled_rw_2"); if (it != overrides_.end()) { return it->second; } else { return server_configurable_flags::GetServerConfigurableFlag( "aconfig_flags.other_namespace", "com.android.aconfig.test.disabled_rw_2", "false") == "true"; } } virtual void disabled_rw_2(bool val) override { overrides_["disabled_rw_2"] = val; } virtual bool enabled_fixed_ro() override { auto it = overrides_.find("enabled_fixed_ro"); if (it != overrides_.end()) { Loading Loading @@ -515,6 +572,15 @@ void set_com_android_aconfig_test_disabled_rw(bool val) { com::android::aconfig::test::disabled_rw(val); } bool com_android_aconfig_test_disabled_rw_2() { return com::android::aconfig::test::disabled_rw_2(); } void set_com_android_aconfig_test_disabled_rw_2(bool val) { com::android::aconfig::test::disabled_rw_2(val); } bool com_android_aconfig_test_enabled_fixed_ro() { return com::android::aconfig::test::enabled_fixed_ro(); Loading tools/aconfig/src/codegen_java.rs +112 −43 Original line number Diff line number Diff line Loading @@ -16,7 +16,7 @@ use anyhow::Result; use serde::Serialize; use std::collections::BTreeSet; use std::collections::{BTreeMap, BTreeSet}; use std::path::PathBuf; use tinytemplate::TinyTemplate; Loading @@ -34,12 +34,14 @@ where { let flag_elements: Vec<FlagElement> = parsed_flags_iter.map(|pf| create_flag_element(package, pf)).collect(); let namespace_flags = gen_flags_by_namespace(&flag_elements); let properties_set: BTreeSet<String> = flag_elements.iter().map(|fe| format_property_name(&fe.device_config_namespace)).collect(); let is_read_write = flag_elements.iter().any(|elem| elem.is_read_write); let is_test_mode = codegen_mode == CodegenMode::Test; let context = Context { flag_elements, namespace_flags, is_test_mode, is_read_write, properties_set, Loading Loading @@ -72,16 +74,44 @@ where .collect::<Result<Vec<OutputFile>>>() } fn gen_flags_by_namespace(flags: &[FlagElement]) -> Vec<NamespaceFlags> { let mut namespace_to_flag: BTreeMap<String, Vec<FlagElement>> = BTreeMap::new(); for flag in flags { match namespace_to_flag.get_mut(&flag.device_config_namespace) { Some(flag_list) => flag_list.push(flag.clone()), None => { namespace_to_flag.insert(flag.device_config_namespace.clone(), vec![flag.clone()]); } } } namespace_to_flag .iter() .map(|(namespace, flags)| NamespaceFlags { namespace: namespace.to_string(), flags: flags.clone(), }) .collect() } #[derive(Serialize)] struct Context { pub flag_elements: Vec<FlagElement>, pub namespace_flags: Vec<NamespaceFlags>, pub is_test_mode: bool, pub is_read_write: bool, pub properties_set: BTreeSet<String>, pub package_name: String, } #[derive(Serialize)] #[derive(Serialize, Debug)] struct NamespaceFlags { pub namespace: String, pub flags: Vec<FlagElement>, } #[derive(Serialize, Clone, Debug)] struct FlagElement { pub default_value: bool, pub device_config_namespace: String, Loading Loading @@ -148,6 +178,8 @@ mod tests { boolean disabledRo(); @UnsupportedAppUsage boolean disabledRw(); @UnsupportedAppUsage boolean disabledRw2(); @com.android.aconfig.annotations.AssumeTrueForR8 @UnsupportedAppUsage boolean enabledFixedRo(); Loading @@ -170,6 +202,8 @@ mod tests { /** @hide */ public static final String FLAG_DISABLED_RW = "com.android.aconfig.test.disabled_rw"; /** @hide */ public static final String FLAG_DISABLED_RW_2 = "com.android.aconfig.test.disabled_rw_2"; /** @hide */ public static final String FLAG_ENABLED_FIXED_RO = "com.android.aconfig.test.enabled_fixed_ro"; /** @hide */ public static final String FLAG_ENABLED_RO = "com.android.aconfig.test.enabled_ro"; Loading @@ -185,6 +219,10 @@ mod tests { public static boolean disabledRw() { return FEATURE_FLAGS.disabledRw(); } @UnsupportedAppUsage public static boolean disabledRw2() { return FEATURE_FLAGS.disabledRw2(); } @com.android.aconfig.annotations.AssumeTrueForR8 @UnsupportedAppUsage public static boolean enabledFixedRo() { Loading Loading @@ -224,6 +262,11 @@ mod tests { } @Override @UnsupportedAppUsage public boolean disabledRw2() { return getValue(Flags.FLAG_DISABLED_RW_2); } @Override @UnsupportedAppUsage public boolean enabledFixedRo() { return getValue(Flags.FLAG_ENABLED_FIXED_RO); } Loading Loading @@ -259,6 +302,7 @@ mod tests { Map.ofEntries( Map.entry(Flags.FLAG_DISABLED_RO, false), Map.entry(Flags.FLAG_DISABLED_RW, false), Map.entry(Flags.FLAG_DISABLED_RW_2, false), Map.entry(Flags.FLAG_ENABLED_FIXED_RO, false), Map.entry(Flags.FLAG_ENABLED_RO, false), Map.entry(Flags.FLAG_ENABLED_RW, false) Loading Loading @@ -289,7 +333,52 @@ mod tests { import android.provider.DeviceConfig.Properties; /** @hide */ public final class FeatureFlagsImpl implements FeatureFlags { private Properties mPropertiesAconfigTest; private static boolean aconfig_test_is_cached = false; private static boolean other_namespace_is_cached = false; private static boolean disabledRw = false; private static boolean disabledRw2 = false; private static boolean enabledRw = true; private void load_overrides_aconfig_test() { try { Properties properties = DeviceConfig.getProperties("aconfig_test"); disabledRw = properties.getBoolean("com.android.aconfig.test.disabled_rw", false); enabledRw = properties.getBoolean("com.android.aconfig.test.enabled_rw", true); } catch (NullPointerException e) { throw new RuntimeException( "Cannot read value from namespace aconfig_test " + "from DeviceConfig. It could be that the code using flag " + "executed before SettingsProvider initialization. Please use " + "fixed read-only flag by adding is_fixed_read_only: true in " + "flag declaration.", e ); } aconfig_test_is_cached = true; } private void load_overrides_other_namespace() { try { Properties properties = DeviceConfig.getProperties("other_namespace"); disabledRw2 = properties.getBoolean("com.android.aconfig.test.disabled_rw_2", false); } catch (NullPointerException e) { throw new RuntimeException( "Cannot read value from namespace other_namespace " + "from DeviceConfig. It could be that the code using flag " + "executed before SettingsProvider initialization. Please use " + "fixed read-only flag by adding is_fixed_read_only: true in " + "flag declaration.", e ); } other_namespace_is_cached = true; } @Override @UnsupportedAppUsage public boolean disabledRo() { Loading @@ -298,18 +387,18 @@ mod tests { @Override @UnsupportedAppUsage public boolean disabledRw() { if (mPropertiesAconfigTest == null) { mPropertiesAconfigTest = getProperties( "aconfig_test", "com.android.aconfig.test.disabled_rw" ); if (!aconfig_test_is_cached) { load_overrides_aconfig_test(); } return mPropertiesAconfigTest .getBoolean( "com.android.aconfig.test.disabled_rw", false ); return disabledRw; } @Override @UnsupportedAppUsage public boolean disabledRw2() { if (!other_namespace_is_cached) { load_overrides_other_namespace(); } return disabledRw2; } @Override @UnsupportedAppUsage Loading @@ -324,36 +413,10 @@ mod tests { @Override @UnsupportedAppUsage public boolean enabledRw() { if (mPropertiesAconfigTest == null) { mPropertiesAconfigTest = getProperties( "aconfig_test", "com.android.aconfig.test.enabled_rw" ); } return mPropertiesAconfigTest .getBoolean( "com.android.aconfig.test.enabled_rw", true ); } private Properties getProperties( String namespace, String flagName) { Properties properties = null; try { properties = DeviceConfig.getProperties(namespace); } catch (NullPointerException e) { throw new RuntimeException( "Cannot read value of flag " + flagName + " from DeviceConfig. " + "It could be that the code using flag executed " + "before SettingsProvider initialization. " + "Please use fixed read-only flag by adding " + "is_fixed_read_only: true in flag declaration.", e ); if (!aconfig_test_is_cached) { load_overrides_aconfig_test(); } return properties; return enabledRw; } } "#; Loading Loading @@ -426,6 +489,12 @@ mod tests { } @Override @UnsupportedAppUsage public boolean disabledRw2() { throw new UnsupportedOperationException( "Method is not implemented."); } @Override @UnsupportedAppUsage public boolean enabledFixedRo() { throw new UnsupportedOperationException( "Method is not implemented."); Loading tools/aconfig/src/codegen_rust.rs +44 −0 Original line number Diff line number Diff line Loading @@ -104,6 +104,12 @@ lazy_static::lazy_static! { "com.android.aconfig.test.disabled_rw", "false") == "true"; /// flag value cache for disabled_rw_2 static ref CACHED_disabled_rw_2: bool = flags_rust::GetServerConfigurableFlag( "aconfig_flags.other_namespace", "com.android.aconfig.test.disabled_rw_2", "false") == "true"; /// flag value cache for enabled_rw static ref CACHED_enabled_rw: bool = flags_rust::GetServerConfigurableFlag( "aconfig_flags.aconfig_test", Loading @@ -122,6 +128,11 @@ impl FlagProvider { *CACHED_disabled_rw } /// query flag disabled_rw_2 pub fn disabled_rw_2(&self) -> bool { *CACHED_disabled_rw_2 } /// query flag enabled_fixed_ro pub fn enabled_fixed_ro(&self) -> bool { true Loading Loading @@ -153,6 +164,12 @@ pub fn disabled_rw() -> bool { PROVIDER.disabled_rw() } /// query flag disabled_rw_2 #[inline(always)] pub fn disabled_rw_2() -> bool { PROVIDER.disabled_rw_2() } /// query flag enabled_fixed_ro #[inline(always)] pub fn enabled_fixed_ro() -> bool { Loading Loading @@ -211,6 +228,21 @@ impl FlagProvider { self.overrides.insert("disabled_rw", val); } /// query flag disabled_rw_2 pub fn disabled_rw_2(&self) -> bool { self.overrides.get("disabled_rw_2").copied().unwrap_or( flags_rust::GetServerConfigurableFlag( "aconfig_flags.other_namespace", "com.android.aconfig.test.disabled_rw_2", "false") == "true" ) } /// set flag disabled_rw_2 pub fn set_disabled_rw_2(&mut self, val: bool) { self.overrides.insert("disabled_rw_2", val); } /// query flag enabled_fixed_ro pub fn enabled_fixed_ro(&self) -> bool { self.overrides.get("enabled_fixed_ro").copied().unwrap_or( Loading Loading @@ -285,6 +317,18 @@ pub fn set_disabled_rw(val: bool) { PROVIDER.lock().unwrap().set_disabled_rw(val); } /// query flag disabled_rw_2 #[inline(always)] pub fn disabled_rw_2() -> bool { PROVIDER.lock().unwrap().disabled_rw_2() } /// set flag disabled_rw_2 #[inline(always)] pub fn set_disabled_rw_2(val: bool) { PROVIDER.lock().unwrap().set_disabled_rw_2(val); } /// query flag enabled_fixed_ro #[inline(always)] pub fn enabled_fixed_ro() -> bool { Loading Loading
tools/aconfig/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -58,6 +58,7 @@ rust_defaults { "libaconfig_protos", "libanyhow", "libclap", "libitertools", "libprotobuf", "libserde", "libserde_json", Loading
tools/aconfig/Cargo.toml +1 −0 Original line number Diff line number Diff line Loading @@ -11,6 +11,7 @@ cargo = [] [dependencies] anyhow = "1.0.69" clap = { version = "4.1.8", features = ["derive"] } itertools = "0.10.5" paste = "1.0.11" protobuf = "3.2.0" serde = { version = "1.0.152", features = ["derive"] } Loading
tools/aconfig/src/codegen_cpp.rs +73 −7 Original line number Diff line number Diff line Loading @@ -32,8 +32,9 @@ where I: Iterator<Item = &'a ProtoParsedFlag>, { let mut readwrite_count = 0; let class_elements: Vec<ClassElement> = parsed_flags_iter.map(|pf| create_class_element(package, pf, &mut readwrite_count)).collect(); let class_elements: Vec<ClassElement> = parsed_flags_iter .map(|pf| create_class_element(package, pf, &mut readwrite_count)) .collect(); let readwrite = readwrite_count > 0; let has_fixed_read_only = class_elements.iter().any(|item| item.is_fixed_read_only); let header = package.replace('.', "_"); Loading Loading @@ -110,7 +111,9 @@ pub struct ClassElement { fn create_class_element(package: &str, pf: &ProtoParsedFlag, rw_count: &mut i32) -> ClassElement { ClassElement { readwrite_idx: if pf.permission() == ProtoFlagPermission::READ_WRITE { let index = *rw_count; *rw_count += 1; index let index = *rw_count; *rw_count += 1; index } else { -1 }, Loading Loading @@ -162,6 +165,8 @@ public: virtual bool disabled_rw() = 0; virtual bool disabled_rw_2() = 0; virtual bool enabled_fixed_ro() = 0; virtual bool enabled_ro() = 0; Loading @@ -179,6 +184,10 @@ inline bool disabled_rw() { return provider_->disabled_rw(); } inline bool disabled_rw_2() { return provider_->disabled_rw_2(); } inline bool enabled_fixed_ro() { return COM_ANDROID_ACONFIG_TEST_ENABLED_FIXED_RO; } Loading @@ -200,6 +209,8 @@ bool com_android_aconfig_test_disabled_ro(); bool com_android_aconfig_test_disabled_rw(); bool com_android_aconfig_test_disabled_rw_2(); bool com_android_aconfig_test_enabled_fixed_ro(); bool com_android_aconfig_test_enabled_ro(); Loading Loading @@ -233,6 +244,10 @@ public: virtual void disabled_rw(bool val) = 0; virtual bool disabled_rw_2() = 0; virtual void disabled_rw_2(bool val) = 0; virtual bool enabled_fixed_ro() = 0; virtual void enabled_fixed_ro(bool val) = 0; Loading Loading @@ -266,6 +281,14 @@ inline void disabled_rw(bool val) { provider_->disabled_rw(val); } inline bool disabled_rw_2() { return provider_->disabled_rw_2(); } inline void disabled_rw_2(bool val) { provider_->disabled_rw_2(val); } inline bool enabled_fixed_ro() { return provider_->enabled_fixed_ro(); } Loading Loading @@ -307,6 +330,10 @@ bool com_android_aconfig_test_disabled_rw(); void set_com_android_aconfig_test_disabled_rw(bool val); bool com_android_aconfig_test_disabled_rw_2(); void set_com_android_aconfig_test_disabled_rw_2(bool val); bool com_android_aconfig_test_enabled_fixed_ro(); void set_com_android_aconfig_test_enabled_fixed_ro(bool val); Loading Loading @@ -352,6 +379,16 @@ namespace com::android::aconfig::test { return cache_[0]; } virtual bool disabled_rw_2() override { if (cache_[1] == -1) { cache_[1] = server_configurable_flags::GetServerConfigurableFlag( "aconfig_flags.other_namespace", "com.android.aconfig.test.disabled_rw_2", "false") == "true"; } return cache_[1]; } virtual bool enabled_fixed_ro() override { return COM_ANDROID_ACONFIG_TEST_ENABLED_FIXED_RO; } Loading @@ -361,18 +398,18 @@ namespace com::android::aconfig::test { } virtual bool enabled_rw() override { if (cache_[1] == -1) { cache_[1] = server_configurable_flags::GetServerConfigurableFlag( if (cache_[2] == -1) { cache_[2] = server_configurable_flags::GetServerConfigurableFlag( "aconfig_flags.aconfig_test", "com.android.aconfig.test.enabled_rw", "true") == "true"; } return cache_[1]; return cache_[2]; } }; std::vector<int8_t> cache_ = std::vector<int8_t>(2, -1); std::vector<int8_t> cache_ = std::vector<int8_t>(3, -1); std::unique_ptr<flag_provider_interface> provider_ = std::make_unique<flag_provider>(); Loading @@ -386,6 +423,10 @@ bool com_android_aconfig_test_disabled_rw() { return com::android::aconfig::test::disabled_rw(); } bool com_android_aconfig_test_disabled_rw_2() { return com::android::aconfig::test::disabled_rw_2(); } bool com_android_aconfig_test_enabled_fixed_ro() { return COM_ANDROID_ACONFIG_TEST_ENABLED_FIXED_RO; } Loading Loading @@ -446,6 +487,22 @@ namespace com::android::aconfig::test { overrides_["disabled_rw"] = val; } virtual bool disabled_rw_2() override { auto it = overrides_.find("disabled_rw_2"); if (it != overrides_.end()) { return it->second; } else { return server_configurable_flags::GetServerConfigurableFlag( "aconfig_flags.other_namespace", "com.android.aconfig.test.disabled_rw_2", "false") == "true"; } } virtual void disabled_rw_2(bool val) override { overrides_["disabled_rw_2"] = val; } virtual bool enabled_fixed_ro() override { auto it = overrides_.find("enabled_fixed_ro"); if (it != overrides_.end()) { Loading Loading @@ -515,6 +572,15 @@ void set_com_android_aconfig_test_disabled_rw(bool val) { com::android::aconfig::test::disabled_rw(val); } bool com_android_aconfig_test_disabled_rw_2() { return com::android::aconfig::test::disabled_rw_2(); } void set_com_android_aconfig_test_disabled_rw_2(bool val) { com::android::aconfig::test::disabled_rw_2(val); } bool com_android_aconfig_test_enabled_fixed_ro() { return com::android::aconfig::test::enabled_fixed_ro(); Loading
tools/aconfig/src/codegen_java.rs +112 −43 Original line number Diff line number Diff line Loading @@ -16,7 +16,7 @@ use anyhow::Result; use serde::Serialize; use std::collections::BTreeSet; use std::collections::{BTreeMap, BTreeSet}; use std::path::PathBuf; use tinytemplate::TinyTemplate; Loading @@ -34,12 +34,14 @@ where { let flag_elements: Vec<FlagElement> = parsed_flags_iter.map(|pf| create_flag_element(package, pf)).collect(); let namespace_flags = gen_flags_by_namespace(&flag_elements); let properties_set: BTreeSet<String> = flag_elements.iter().map(|fe| format_property_name(&fe.device_config_namespace)).collect(); let is_read_write = flag_elements.iter().any(|elem| elem.is_read_write); let is_test_mode = codegen_mode == CodegenMode::Test; let context = Context { flag_elements, namespace_flags, is_test_mode, is_read_write, properties_set, Loading Loading @@ -72,16 +74,44 @@ where .collect::<Result<Vec<OutputFile>>>() } fn gen_flags_by_namespace(flags: &[FlagElement]) -> Vec<NamespaceFlags> { let mut namespace_to_flag: BTreeMap<String, Vec<FlagElement>> = BTreeMap::new(); for flag in flags { match namespace_to_flag.get_mut(&flag.device_config_namespace) { Some(flag_list) => flag_list.push(flag.clone()), None => { namespace_to_flag.insert(flag.device_config_namespace.clone(), vec![flag.clone()]); } } } namespace_to_flag .iter() .map(|(namespace, flags)| NamespaceFlags { namespace: namespace.to_string(), flags: flags.clone(), }) .collect() } #[derive(Serialize)] struct Context { pub flag_elements: Vec<FlagElement>, pub namespace_flags: Vec<NamespaceFlags>, pub is_test_mode: bool, pub is_read_write: bool, pub properties_set: BTreeSet<String>, pub package_name: String, } #[derive(Serialize)] #[derive(Serialize, Debug)] struct NamespaceFlags { pub namespace: String, pub flags: Vec<FlagElement>, } #[derive(Serialize, Clone, Debug)] struct FlagElement { pub default_value: bool, pub device_config_namespace: String, Loading Loading @@ -148,6 +178,8 @@ mod tests { boolean disabledRo(); @UnsupportedAppUsage boolean disabledRw(); @UnsupportedAppUsage boolean disabledRw2(); @com.android.aconfig.annotations.AssumeTrueForR8 @UnsupportedAppUsage boolean enabledFixedRo(); Loading @@ -170,6 +202,8 @@ mod tests { /** @hide */ public static final String FLAG_DISABLED_RW = "com.android.aconfig.test.disabled_rw"; /** @hide */ public static final String FLAG_DISABLED_RW_2 = "com.android.aconfig.test.disabled_rw_2"; /** @hide */ public static final String FLAG_ENABLED_FIXED_RO = "com.android.aconfig.test.enabled_fixed_ro"; /** @hide */ public static final String FLAG_ENABLED_RO = "com.android.aconfig.test.enabled_ro"; Loading @@ -185,6 +219,10 @@ mod tests { public static boolean disabledRw() { return FEATURE_FLAGS.disabledRw(); } @UnsupportedAppUsage public static boolean disabledRw2() { return FEATURE_FLAGS.disabledRw2(); } @com.android.aconfig.annotations.AssumeTrueForR8 @UnsupportedAppUsage public static boolean enabledFixedRo() { Loading Loading @@ -224,6 +262,11 @@ mod tests { } @Override @UnsupportedAppUsage public boolean disabledRw2() { return getValue(Flags.FLAG_DISABLED_RW_2); } @Override @UnsupportedAppUsage public boolean enabledFixedRo() { return getValue(Flags.FLAG_ENABLED_FIXED_RO); } Loading Loading @@ -259,6 +302,7 @@ mod tests { Map.ofEntries( Map.entry(Flags.FLAG_DISABLED_RO, false), Map.entry(Flags.FLAG_DISABLED_RW, false), Map.entry(Flags.FLAG_DISABLED_RW_2, false), Map.entry(Flags.FLAG_ENABLED_FIXED_RO, false), Map.entry(Flags.FLAG_ENABLED_RO, false), Map.entry(Flags.FLAG_ENABLED_RW, false) Loading Loading @@ -289,7 +333,52 @@ mod tests { import android.provider.DeviceConfig.Properties; /** @hide */ public final class FeatureFlagsImpl implements FeatureFlags { private Properties mPropertiesAconfigTest; private static boolean aconfig_test_is_cached = false; private static boolean other_namespace_is_cached = false; private static boolean disabledRw = false; private static boolean disabledRw2 = false; private static boolean enabledRw = true; private void load_overrides_aconfig_test() { try { Properties properties = DeviceConfig.getProperties("aconfig_test"); disabledRw = properties.getBoolean("com.android.aconfig.test.disabled_rw", false); enabledRw = properties.getBoolean("com.android.aconfig.test.enabled_rw", true); } catch (NullPointerException e) { throw new RuntimeException( "Cannot read value from namespace aconfig_test " + "from DeviceConfig. It could be that the code using flag " + "executed before SettingsProvider initialization. Please use " + "fixed read-only flag by adding is_fixed_read_only: true in " + "flag declaration.", e ); } aconfig_test_is_cached = true; } private void load_overrides_other_namespace() { try { Properties properties = DeviceConfig.getProperties("other_namespace"); disabledRw2 = properties.getBoolean("com.android.aconfig.test.disabled_rw_2", false); } catch (NullPointerException e) { throw new RuntimeException( "Cannot read value from namespace other_namespace " + "from DeviceConfig. It could be that the code using flag " + "executed before SettingsProvider initialization. Please use " + "fixed read-only flag by adding is_fixed_read_only: true in " + "flag declaration.", e ); } other_namespace_is_cached = true; } @Override @UnsupportedAppUsage public boolean disabledRo() { Loading @@ -298,18 +387,18 @@ mod tests { @Override @UnsupportedAppUsage public boolean disabledRw() { if (mPropertiesAconfigTest == null) { mPropertiesAconfigTest = getProperties( "aconfig_test", "com.android.aconfig.test.disabled_rw" ); if (!aconfig_test_is_cached) { load_overrides_aconfig_test(); } return mPropertiesAconfigTest .getBoolean( "com.android.aconfig.test.disabled_rw", false ); return disabledRw; } @Override @UnsupportedAppUsage public boolean disabledRw2() { if (!other_namespace_is_cached) { load_overrides_other_namespace(); } return disabledRw2; } @Override @UnsupportedAppUsage Loading @@ -324,36 +413,10 @@ mod tests { @Override @UnsupportedAppUsage public boolean enabledRw() { if (mPropertiesAconfigTest == null) { mPropertiesAconfigTest = getProperties( "aconfig_test", "com.android.aconfig.test.enabled_rw" ); } return mPropertiesAconfigTest .getBoolean( "com.android.aconfig.test.enabled_rw", true ); } private Properties getProperties( String namespace, String flagName) { Properties properties = null; try { properties = DeviceConfig.getProperties(namespace); } catch (NullPointerException e) { throw new RuntimeException( "Cannot read value of flag " + flagName + " from DeviceConfig. " + "It could be that the code using flag executed " + "before SettingsProvider initialization. " + "Please use fixed read-only flag by adding " + "is_fixed_read_only: true in flag declaration.", e ); if (!aconfig_test_is_cached) { load_overrides_aconfig_test(); } return properties; return enabledRw; } } "#; Loading Loading @@ -426,6 +489,12 @@ mod tests { } @Override @UnsupportedAppUsage public boolean disabledRw2() { throw new UnsupportedOperationException( "Method is not implemented."); } @Override @UnsupportedAppUsage public boolean enabledFixedRo() { throw new UnsupportedOperationException( "Method is not implemented."); Loading
tools/aconfig/src/codegen_rust.rs +44 −0 Original line number Diff line number Diff line Loading @@ -104,6 +104,12 @@ lazy_static::lazy_static! { "com.android.aconfig.test.disabled_rw", "false") == "true"; /// flag value cache for disabled_rw_2 static ref CACHED_disabled_rw_2: bool = flags_rust::GetServerConfigurableFlag( "aconfig_flags.other_namespace", "com.android.aconfig.test.disabled_rw_2", "false") == "true"; /// flag value cache for enabled_rw static ref CACHED_enabled_rw: bool = flags_rust::GetServerConfigurableFlag( "aconfig_flags.aconfig_test", Loading @@ -122,6 +128,11 @@ impl FlagProvider { *CACHED_disabled_rw } /// query flag disabled_rw_2 pub fn disabled_rw_2(&self) -> bool { *CACHED_disabled_rw_2 } /// query flag enabled_fixed_ro pub fn enabled_fixed_ro(&self) -> bool { true Loading Loading @@ -153,6 +164,12 @@ pub fn disabled_rw() -> bool { PROVIDER.disabled_rw() } /// query flag disabled_rw_2 #[inline(always)] pub fn disabled_rw_2() -> bool { PROVIDER.disabled_rw_2() } /// query flag enabled_fixed_ro #[inline(always)] pub fn enabled_fixed_ro() -> bool { Loading Loading @@ -211,6 +228,21 @@ impl FlagProvider { self.overrides.insert("disabled_rw", val); } /// query flag disabled_rw_2 pub fn disabled_rw_2(&self) -> bool { self.overrides.get("disabled_rw_2").copied().unwrap_or( flags_rust::GetServerConfigurableFlag( "aconfig_flags.other_namespace", "com.android.aconfig.test.disabled_rw_2", "false") == "true" ) } /// set flag disabled_rw_2 pub fn set_disabled_rw_2(&mut self, val: bool) { self.overrides.insert("disabled_rw_2", val); } /// query flag enabled_fixed_ro pub fn enabled_fixed_ro(&self) -> bool { self.overrides.get("enabled_fixed_ro").copied().unwrap_or( Loading Loading @@ -285,6 +317,18 @@ pub fn set_disabled_rw(val: bool) { PROVIDER.lock().unwrap().set_disabled_rw(val); } /// query flag disabled_rw_2 #[inline(always)] pub fn disabled_rw_2() -> bool { PROVIDER.lock().unwrap().disabled_rw_2() } /// set flag disabled_rw_2 #[inline(always)] pub fn set_disabled_rw_2(val: bool) { PROVIDER.lock().unwrap().set_disabled_rw_2(val); } /// query flag enabled_fixed_ro #[inline(always)] pub fn enabled_fixed_ro() -> bool { Loading