Loading tools/aconfig/fake_device_config/src/android/provider/DeviceConfig.java +0 −10 Original line number Diff line number Diff line Loading @@ -26,14 +26,4 @@ public class DeviceConfig { public static boolean getBoolean(String ns, String name, boolean def) { return false; } public static Properties getProperties(String namespace, String... names) { return new Properties(); } public static class Properties { public boolean getBoolean(String name, boolean def) { return false; } } } tools/aconfig/src/codegen_java.rs +47 −117 Original line number Diff line number Diff line Loading @@ -16,7 +16,6 @@ use anyhow::Result; use serde::Serialize; use std::collections::BTreeSet; use std::path::PathBuf; use tinytemplate::TinyTemplate; Loading @@ -32,19 +31,12 @@ pub fn generate_java_code<'a, I>( where I: Iterator<Item = &'a ProtoParsedFlag>, { let flag_elements: Vec<FlagElement> = parsed_flags_iter.map(|pf| create_flag_element(package, pf)).collect(); 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 class_elements: Vec<ClassElement> = parsed_flags_iter.map(|pf| create_class_element(package, pf)).collect(); let is_read_write = class_elements.iter().any(|elem| elem.is_read_write); let is_test_mode = codegen_mode == CodegenMode::Test; let context = Context { flag_elements, is_test_mode, is_read_write, properties_set, package_name: package.to_string(), }; let context = Context { class_elements, is_test_mode, is_read_write, package_name: package.to_string() }; let mut template = TinyTemplate::new(); template.add_template("Flags.java", include_str!("../templates/Flags.java.template"))?; template.add_template( Loading Loading @@ -74,46 +66,39 @@ where #[derive(Serialize)] struct Context { pub flag_elements: Vec<FlagElement>, pub class_elements: Vec<ClassElement>, pub is_test_mode: bool, pub is_read_write: bool, pub properties_set: BTreeSet<String>, pub package_name: String, } #[derive(Serialize)] struct FlagElement { struct ClassElement { pub default_value: bool, pub device_config_namespace: String, pub device_config_flag: String, pub flag_name_constant_suffix: String, pub is_read_write: bool, pub method_name: String, pub properties: String, } fn create_flag_element(package: &str, pf: &ProtoParsedFlag) -> FlagElement { fn create_class_element(package: &str, pf: &ProtoParsedFlag) -> ClassElement { let device_config_flag = codegen::create_device_config_ident(package, pf.name()) .expect("values checked at flag parse time"); FlagElement { ClassElement { default_value: pf.state() == ProtoFlagState::ENABLED, device_config_namespace: pf.namespace().to_string(), device_config_flag, flag_name_constant_suffix: pf.name().to_ascii_uppercase(), is_read_write: pf.permission() == ProtoFlagPermission::READ_WRITE, method_name: format_java_method_name(pf.name()), properties: format_property_name(pf.namespace()), } } fn format_java_method_name(flag_name: &str) -> String { let splits: Vec<&str> = flag_name.split('_').filter(|&word| !word.is_empty()).collect(); if splits.len() == 1 { let name = splits[0]; name[0..1].to_ascii_lowercase() + &name[1..] } else { splits .iter() flag_name .split('_') .filter(|&word| !word.is_empty()) .enumerate() .map(|(index, word)| { if index == 0 { Loading @@ -125,12 +110,6 @@ fn format_java_method_name(flag_name: &str) -> String { .collect::<Vec<String>>() .join("") } } fn format_property_name(property_name: &str) -> String { let name = format_java_method_name(property_name); format!("mProperties{}{}", &name[0..1].to_ascii_uppercase(), &name[1..]) } #[cfg(test)] mod tests { Loading Loading @@ -286,10 +265,8 @@ mod tests { // TODO(b/303773055): Remove the annotation after access issue is resolved. import android.compat.annotation.UnsupportedAppUsage; import android.provider.DeviceConfig; import android.provider.DeviceConfig.Properties; /** @hide */ public final class FeatureFlagsImpl implements FeatureFlags { private Properties mPropertiesAconfigTest; @Override @UnsupportedAppUsage public boolean disabledRo() { Loading @@ -298,15 +275,8 @@ mod tests { @Override @UnsupportedAppUsage public boolean disabledRw() { if (mPropertiesAconfigTest == null) { mPropertiesAconfigTest = getProperties( return getValue( "aconfig_test", "com.android.aconfig.test.disabled_rw" ); } return mPropertiesAconfigTest .getBoolean( "com.android.aconfig.test.disabled_rw", false ); Loading @@ -324,36 +294,32 @@ mod tests { @Override @UnsupportedAppUsage public boolean enabledRw() { if (mPropertiesAconfigTest == null) { mPropertiesAconfigTest = getProperties( return getValue( "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; private boolean getValue(String nameSpace, String flagName, boolean defaultValue) { boolean value = defaultValue; try { properties = DeviceConfig.getProperties(namespace); value = DeviceConfig.getBoolean( nameSpace, flagName, defaultValue ); } 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.", "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 ); } return properties; return value; } } "#; Loading Loading @@ -475,45 +441,9 @@ mod tests { #[test] fn test_format_java_method_name() { let expected = "someSnakeName"; let input = "____some_snake___name____"; let expected = "someSnakeName"; let formatted_name = format_java_method_name(input); assert_eq!(expected, formatted_name); let input = "someSnakeName"; let formatted_name = format_java_method_name(input); assert_eq!(expected, formatted_name); let input = "SomeSnakeName"; let formatted_name = format_java_method_name(input); assert_eq!(expected, formatted_name); let input = "SomeSnakeName_"; let formatted_name = format_java_method_name(input); assert_eq!(expected, formatted_name); let input = "_SomeSnakeName"; let formatted_name = format_java_method_name(input); assert_eq!(expected, formatted_name); } #[test] fn test_format_property_name() { let expected = "mPropertiesSomeSnakeName"; let input = "____some_snake___name____"; let formatted_name = format_property_name(input); assert_eq!(expected, formatted_name); let input = "someSnakeName"; let formatted_name = format_property_name(input); assert_eq!(expected, formatted_name); let input = "SomeSnakeName"; let formatted_name = format_property_name(input); assert_eq!(expected, formatted_name); let input = "SomeSnakeName_"; let formatted_name = format_property_name(input); assert_eq!(expected, formatted_name); } } tools/aconfig/templates/FakeFeatureFlagsImpl.java.template +2 −2 Original line number Diff line number Diff line Loading @@ -11,7 +11,7 @@ public class FakeFeatureFlagsImpl implements FeatureFlags \{ resetAll(); } {{ for item in flag_elements}} {{ for item in class_elements}} @Override @UnsupportedAppUsage public boolean {item.method_name}() \{ Loading Loading @@ -41,7 +41,7 @@ public class FakeFeatureFlagsImpl implements FeatureFlags \{ private Map<String, Boolean> mFlagMap = new HashMap<>( Map.ofEntries( {{-for item in flag_elements}} {{-for item in class_elements}} Map.entry(Flags.FLAG_{item.flag_name_constant_suffix}, false) {{ -if not @last }},{{ endif }} {{ -endfor }} Loading tools/aconfig/templates/FeatureFlags.java.template +1 −1 Original line number Diff line number Diff line Loading @@ -4,7 +4,7 @@ import android.compat.annotation.UnsupportedAppUsage; /** @hide */ public interface FeatureFlags \{ {{ for item in flag_elements }} {{ for item in class_elements}} {{ -if not item.is_read_write }} {{ -if item.default_value }} @com.android.aconfig.annotations.AssumeTrueForR8 Loading tools/aconfig/templates/FeatureFlagsImpl.java.template +26 −39 Original line number Diff line number Diff line Loading @@ -4,58 +4,45 @@ import android.compat.annotation.UnsupportedAppUsage; {{ if not is_test_mode }} {{ if is_read_write- }} import android.provider.DeviceConfig; import android.provider.DeviceConfig.Properties; {{ endif }} /** @hide */ public final class FeatureFlagsImpl implements FeatureFlags \{ {{ if is_read_write- }} {{ for properties in properties_set }} private Properties {properties}; {{ endfor }} {{ endif- }} {{ for flag in flag_elements }} {{ for item in class_elements}} @Override @UnsupportedAppUsage public boolean {flag.method_name}() \{ {{ -if flag.is_read_write }} if ({flag.properties} == null) \{ {flag.properties} = getProperties( "{flag.device_config_namespace}", "{flag.device_config_flag}" ); } return {flag.properties} .getBoolean( "{flag.device_config_flag}", {flag.default_value} public boolean {item.method_name}() \{ {{ -if item.is_read_write }} return getValue( "{item.device_config_namespace}", "{item.device_config_flag}", {item.default_value} ); {{ else }} return {flag.default_value}; return {item.default_value}; {{ endif- }} } {{ endfor }} {{ -if is_read_write }} private Properties getProperties( String namespace, String flagName) \{ Properties properties = null; {{ if is_read_write- }} private boolean getValue(String nameSpace, String flagName, boolean defaultValue) \{ boolean value = defaultValue; try \{ properties = DeviceConfig.getProperties(namespace); value = DeviceConfig.getBoolean( nameSpace, flagName, defaultValue ); } 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.", "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 ); } return properties; return value; } {{ endif- }} } Loading @@ -63,10 +50,10 @@ public final class FeatureFlagsImpl implements FeatureFlags \{ {#- Generate only stub if in test mode #} /** @hide */ public final class FeatureFlagsImpl implements FeatureFlags \{ {{ for flag in flag_elements }} {{ for item in class_elements}} @Override @UnsupportedAppUsage public boolean {flag.method_name}() \{ public boolean {item.method_name}() \{ throw new UnsupportedOperationException( "Method is not implemented."); } Loading Loading
tools/aconfig/fake_device_config/src/android/provider/DeviceConfig.java +0 −10 Original line number Diff line number Diff line Loading @@ -26,14 +26,4 @@ public class DeviceConfig { public static boolean getBoolean(String ns, String name, boolean def) { return false; } public static Properties getProperties(String namespace, String... names) { return new Properties(); } public static class Properties { public boolean getBoolean(String name, boolean def) { return false; } } }
tools/aconfig/src/codegen_java.rs +47 −117 Original line number Diff line number Diff line Loading @@ -16,7 +16,6 @@ use anyhow::Result; use serde::Serialize; use std::collections::BTreeSet; use std::path::PathBuf; use tinytemplate::TinyTemplate; Loading @@ -32,19 +31,12 @@ pub fn generate_java_code<'a, I>( where I: Iterator<Item = &'a ProtoParsedFlag>, { let flag_elements: Vec<FlagElement> = parsed_flags_iter.map(|pf| create_flag_element(package, pf)).collect(); 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 class_elements: Vec<ClassElement> = parsed_flags_iter.map(|pf| create_class_element(package, pf)).collect(); let is_read_write = class_elements.iter().any(|elem| elem.is_read_write); let is_test_mode = codegen_mode == CodegenMode::Test; let context = Context { flag_elements, is_test_mode, is_read_write, properties_set, package_name: package.to_string(), }; let context = Context { class_elements, is_test_mode, is_read_write, package_name: package.to_string() }; let mut template = TinyTemplate::new(); template.add_template("Flags.java", include_str!("../templates/Flags.java.template"))?; template.add_template( Loading Loading @@ -74,46 +66,39 @@ where #[derive(Serialize)] struct Context { pub flag_elements: Vec<FlagElement>, pub class_elements: Vec<ClassElement>, pub is_test_mode: bool, pub is_read_write: bool, pub properties_set: BTreeSet<String>, pub package_name: String, } #[derive(Serialize)] struct FlagElement { struct ClassElement { pub default_value: bool, pub device_config_namespace: String, pub device_config_flag: String, pub flag_name_constant_suffix: String, pub is_read_write: bool, pub method_name: String, pub properties: String, } fn create_flag_element(package: &str, pf: &ProtoParsedFlag) -> FlagElement { fn create_class_element(package: &str, pf: &ProtoParsedFlag) -> ClassElement { let device_config_flag = codegen::create_device_config_ident(package, pf.name()) .expect("values checked at flag parse time"); FlagElement { ClassElement { default_value: pf.state() == ProtoFlagState::ENABLED, device_config_namespace: pf.namespace().to_string(), device_config_flag, flag_name_constant_suffix: pf.name().to_ascii_uppercase(), is_read_write: pf.permission() == ProtoFlagPermission::READ_WRITE, method_name: format_java_method_name(pf.name()), properties: format_property_name(pf.namespace()), } } fn format_java_method_name(flag_name: &str) -> String { let splits: Vec<&str> = flag_name.split('_').filter(|&word| !word.is_empty()).collect(); if splits.len() == 1 { let name = splits[0]; name[0..1].to_ascii_lowercase() + &name[1..] } else { splits .iter() flag_name .split('_') .filter(|&word| !word.is_empty()) .enumerate() .map(|(index, word)| { if index == 0 { Loading @@ -125,12 +110,6 @@ fn format_java_method_name(flag_name: &str) -> String { .collect::<Vec<String>>() .join("") } } fn format_property_name(property_name: &str) -> String { let name = format_java_method_name(property_name); format!("mProperties{}{}", &name[0..1].to_ascii_uppercase(), &name[1..]) } #[cfg(test)] mod tests { Loading Loading @@ -286,10 +265,8 @@ mod tests { // TODO(b/303773055): Remove the annotation after access issue is resolved. import android.compat.annotation.UnsupportedAppUsage; import android.provider.DeviceConfig; import android.provider.DeviceConfig.Properties; /** @hide */ public final class FeatureFlagsImpl implements FeatureFlags { private Properties mPropertiesAconfigTest; @Override @UnsupportedAppUsage public boolean disabledRo() { Loading @@ -298,15 +275,8 @@ mod tests { @Override @UnsupportedAppUsage public boolean disabledRw() { if (mPropertiesAconfigTest == null) { mPropertiesAconfigTest = getProperties( return getValue( "aconfig_test", "com.android.aconfig.test.disabled_rw" ); } return mPropertiesAconfigTest .getBoolean( "com.android.aconfig.test.disabled_rw", false ); Loading @@ -324,36 +294,32 @@ mod tests { @Override @UnsupportedAppUsage public boolean enabledRw() { if (mPropertiesAconfigTest == null) { mPropertiesAconfigTest = getProperties( return getValue( "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; private boolean getValue(String nameSpace, String flagName, boolean defaultValue) { boolean value = defaultValue; try { properties = DeviceConfig.getProperties(namespace); value = DeviceConfig.getBoolean( nameSpace, flagName, defaultValue ); } 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.", "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 ); } return properties; return value; } } "#; Loading Loading @@ -475,45 +441,9 @@ mod tests { #[test] fn test_format_java_method_name() { let expected = "someSnakeName"; let input = "____some_snake___name____"; let expected = "someSnakeName"; let formatted_name = format_java_method_name(input); assert_eq!(expected, formatted_name); let input = "someSnakeName"; let formatted_name = format_java_method_name(input); assert_eq!(expected, formatted_name); let input = "SomeSnakeName"; let formatted_name = format_java_method_name(input); assert_eq!(expected, formatted_name); let input = "SomeSnakeName_"; let formatted_name = format_java_method_name(input); assert_eq!(expected, formatted_name); let input = "_SomeSnakeName"; let formatted_name = format_java_method_name(input); assert_eq!(expected, formatted_name); } #[test] fn test_format_property_name() { let expected = "mPropertiesSomeSnakeName"; let input = "____some_snake___name____"; let formatted_name = format_property_name(input); assert_eq!(expected, formatted_name); let input = "someSnakeName"; let formatted_name = format_property_name(input); assert_eq!(expected, formatted_name); let input = "SomeSnakeName"; let formatted_name = format_property_name(input); assert_eq!(expected, formatted_name); let input = "SomeSnakeName_"; let formatted_name = format_property_name(input); assert_eq!(expected, formatted_name); } }
tools/aconfig/templates/FakeFeatureFlagsImpl.java.template +2 −2 Original line number Diff line number Diff line Loading @@ -11,7 +11,7 @@ public class FakeFeatureFlagsImpl implements FeatureFlags \{ resetAll(); } {{ for item in flag_elements}} {{ for item in class_elements}} @Override @UnsupportedAppUsage public boolean {item.method_name}() \{ Loading Loading @@ -41,7 +41,7 @@ public class FakeFeatureFlagsImpl implements FeatureFlags \{ private Map<String, Boolean> mFlagMap = new HashMap<>( Map.ofEntries( {{-for item in flag_elements}} {{-for item in class_elements}} Map.entry(Flags.FLAG_{item.flag_name_constant_suffix}, false) {{ -if not @last }},{{ endif }} {{ -endfor }} Loading
tools/aconfig/templates/FeatureFlags.java.template +1 −1 Original line number Diff line number Diff line Loading @@ -4,7 +4,7 @@ import android.compat.annotation.UnsupportedAppUsage; /** @hide */ public interface FeatureFlags \{ {{ for item in flag_elements }} {{ for item in class_elements}} {{ -if not item.is_read_write }} {{ -if item.default_value }} @com.android.aconfig.annotations.AssumeTrueForR8 Loading
tools/aconfig/templates/FeatureFlagsImpl.java.template +26 −39 Original line number Diff line number Diff line Loading @@ -4,58 +4,45 @@ import android.compat.annotation.UnsupportedAppUsage; {{ if not is_test_mode }} {{ if is_read_write- }} import android.provider.DeviceConfig; import android.provider.DeviceConfig.Properties; {{ endif }} /** @hide */ public final class FeatureFlagsImpl implements FeatureFlags \{ {{ if is_read_write- }} {{ for properties in properties_set }} private Properties {properties}; {{ endfor }} {{ endif- }} {{ for flag in flag_elements }} {{ for item in class_elements}} @Override @UnsupportedAppUsage public boolean {flag.method_name}() \{ {{ -if flag.is_read_write }} if ({flag.properties} == null) \{ {flag.properties} = getProperties( "{flag.device_config_namespace}", "{flag.device_config_flag}" ); } return {flag.properties} .getBoolean( "{flag.device_config_flag}", {flag.default_value} public boolean {item.method_name}() \{ {{ -if item.is_read_write }} return getValue( "{item.device_config_namespace}", "{item.device_config_flag}", {item.default_value} ); {{ else }} return {flag.default_value}; return {item.default_value}; {{ endif- }} } {{ endfor }} {{ -if is_read_write }} private Properties getProperties( String namespace, String flagName) \{ Properties properties = null; {{ if is_read_write- }} private boolean getValue(String nameSpace, String flagName, boolean defaultValue) \{ boolean value = defaultValue; try \{ properties = DeviceConfig.getProperties(namespace); value = DeviceConfig.getBoolean( nameSpace, flagName, defaultValue ); } 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.", "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 ); } return properties; return value; } {{ endif- }} } Loading @@ -63,10 +50,10 @@ public final class FeatureFlagsImpl implements FeatureFlags \{ {#- Generate only stub if in test mode #} /** @hide */ public final class FeatureFlagsImpl implements FeatureFlags \{ {{ for flag in flag_elements }} {{ for item in class_elements}} @Override @UnsupportedAppUsage public boolean {flag.method_name}() \{ public boolean {item.method_name}() \{ throw new UnsupportedOperationException( "Method is not implemented."); } Loading