Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 257f6434 authored by Zhi Dou's avatar Zhi Dou Committed by Gerrit Code Review
Browse files

Revert "aconfig: cache flag value in generated java code"

This reverts commit 3dea629a.

Reason for revert: b/308228560

Change-Id: I6511def2e53ab793c5fd78f65bea14eeebc5cdb2
parent 3dea629a
Loading
Loading
Loading
Loading
+0 −10
Original line number Diff line number Diff line
@@ -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;
		}
	}
}
+47 −117
Original line number Diff line number Diff line
@@ -16,7 +16,6 @@

use anyhow::Result;
use serde::Serialize;
use std::collections::BTreeSet;
use std::path::PathBuf;
use tinytemplate::TinyTemplate;

@@ -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(
@@ -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 {
@@ -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 {
@@ -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() {
@@ -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
                );
@@ -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;
            }
        }
        "#;
@@ -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);
    }
}
+2 −2
Original line number Diff line number Diff line
@@ -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}() \{
@@ -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 }}
+1 −1
Original line number Diff line number Diff line
@@ -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
+26 −39
Original line number Diff line number Diff line
@@ -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- }}
}
@@ -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