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

Commit 04dfa3fd authored by Ted Bauer's avatar Ted Bauer Committed by Automerger Merge Worker
Browse files

Merge "Cache Java codegen'd flags in static member variables." into main am: 99b189ac

parents 0379fe98 99b189ac
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -58,6 +58,7 @@ rust_defaults {
        "libaconfig_protos",
        "libaconfig_protos",
        "libanyhow",
        "libanyhow",
        "libclap",
        "libclap",
        "libitertools",
        "libprotobuf",
        "libprotobuf",
        "libserde",
        "libserde",
        "libserde_json",
        "libserde_json",
+1 −0
Original line number Original line Diff line number Diff line
@@ -11,6 +11,7 @@ cargo = []
[dependencies]
[dependencies]
anyhow = "1.0.69"
anyhow = "1.0.69"
clap = { version = "4.1.8", features = ["derive"] }
clap = { version = "4.1.8", features = ["derive"] }
itertools = "0.10.5"
paste = "1.0.11"
paste = "1.0.11"
protobuf = "3.2.0"
protobuf = "3.2.0"
serde = { version = "1.0.152", features = ["derive"] }
serde = { version = "1.0.152", features = ["derive"] }
+39 −41
Original line number Original line Diff line number Diff line
@@ -15,6 +15,7 @@
 */
 */


use anyhow::Result;
use anyhow::Result;
use itertools::Itertools;
use serde::Serialize;
use serde::Serialize;
use std::collections::BTreeSet;
use std::collections::BTreeSet;
use std::path::PathBuf;
use std::path::PathBuf;
@@ -34,12 +35,18 @@ where
{
{
    let flag_elements: Vec<FlagElement> =
    let flag_elements: Vec<FlagElement> =
        parsed_flags_iter.map(|pf| create_flag_element(package, pf)).collect();
        parsed_flags_iter.map(|pf| create_flag_element(package, pf)).collect();
    let namespace_set: BTreeSet<String> = flag_elements
        .iter()
        .unique_by(|f| &f.device_config_namespace)
        .map(|f| f.device_config_namespace.clone())
        .collect();
    let properties_set: BTreeSet<String> =
    let properties_set: BTreeSet<String> =
        flag_elements.iter().map(|fe| format_property_name(&fe.device_config_namespace)).collect();
        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_read_write = flag_elements.iter().any(|elem| elem.is_read_write);
    let is_test_mode = codegen_mode == CodegenMode::Test;
    let is_test_mode = codegen_mode == CodegenMode::Test;
    let context = Context {
    let context = Context {
        flag_elements,
        flag_elements,
        namespace_set,
        is_test_mode,
        is_test_mode,
        is_read_write,
        is_read_write,
        properties_set,
        properties_set,
@@ -75,6 +82,7 @@ where
#[derive(Serialize)]
#[derive(Serialize)]
struct Context {
struct Context {
    pub flag_elements: Vec<FlagElement>,
    pub flag_elements: Vec<FlagElement>,
    pub namespace_set: BTreeSet<String>,
    pub is_test_mode: bool,
    pub is_test_mode: bool,
    pub is_read_write: bool,
    pub is_read_write: bool,
    pub properties_set: BTreeSet<String>,
    pub properties_set: BTreeSet<String>,
@@ -289,7 +297,31 @@ mod tests {
        import android.provider.DeviceConfig.Properties;
        import android.provider.DeviceConfig.Properties;
        /** @hide */
        /** @hide */
        public final class FeatureFlagsImpl implements FeatureFlags {
        public final class FeatureFlagsImpl implements FeatureFlags {
            private Properties mPropertiesAconfigTest;
            private static boolean aconfig_test_is_cached = false;
            private static boolean disabledRw = 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;
            }

            @Override
            @Override
            @UnsupportedAppUsage
            @UnsupportedAppUsage
            public boolean disabledRo() {
            public boolean disabledRo() {
@@ -298,18 +330,10 @@ mod tests {
            @Override
            @Override
            @UnsupportedAppUsage
            @UnsupportedAppUsage
            public boolean disabledRw() {
            public boolean disabledRw() {
                if (mPropertiesAconfigTest == null) {
                if (!aconfig_test_is_cached) {
                    mPropertiesAconfigTest =
                    load_overrides_aconfig_test();
                        getProperties(
                            "aconfig_test",
                            "com.android.aconfig.test.disabled_rw"
                        );
                }
                }
                return mPropertiesAconfigTest
                return disabledRw;
                    .getBoolean(
                        "com.android.aconfig.test.disabled_rw",
                        false
                    );
            }
            }
            @Override
            @Override
            @UnsupportedAppUsage
            @UnsupportedAppUsage
@@ -324,36 +348,10 @@ mod tests {
            @Override
            @Override
            @UnsupportedAppUsage
            @UnsupportedAppUsage
            public boolean enabledRw() {
            public boolean enabledRw() {
                if (mPropertiesAconfigTest == null) {
                if (!aconfig_test_is_cached) {
                    mPropertiesAconfigTest =
                    load_overrides_aconfig_test();
                        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
                    );
                }
                }
                return properties;
                return enabledRw;
            }
            }
        }
        }
        "#;
        "#;
+38 −37
Original line number Original line Diff line number Diff line
@@ -8,57 +8,58 @@ import android.provider.DeviceConfig.Properties;
{{ endif }}
{{ endif }}
/** @hide */
/** @hide */
public final class FeatureFlagsImpl implements FeatureFlags \{
public final class FeatureFlagsImpl implements FeatureFlags \{
{{ if is_read_write- }}
{{- if is_read_write }}
{{ for properties in properties_set }}
{{- for namespace in namespace_set }}
    private Properties {properties};
    private static boolean {namespace}_is_cached = false;
{{ endfor }}
{{- endfor- }}
{{ endif- }}


{{ for flag in flag_elements }}
{{ for flag in flag_elements }}
    @Override
    @UnsupportedAppUsage
    public boolean {flag.method_name}() \{
{{- if flag.is_read_write }}
{{- if flag.is_read_write }}
        if ({flag.properties} == null) \{
    private static boolean {flag.method_name} = {flag.default_value};
            {flag.properties} =
{{- endif- }}
                getProperties(
                    "{flag.device_config_namespace}",
                    "{flag.device_config_flag}"
                );
        }
        return {flag.properties}
                .getBoolean(
                    "{flag.device_config_flag}",
                    {flag.default_value}
                );
    {{ else }}
        return {flag.default_value};
    {{ endif- }}
    }
{{ endfor }}
{{ endfor }}


{{ -if is_read_write }}
{{ for namespace in namespace_set }}
    private Properties getProperties(
    private void load_overrides_{namespace}() \{
            String namespace,
            String flagName) \{
        Properties properties = null;
        try \{
        try \{
            properties = DeviceConfig.getProperties(namespace);
            Properties properties = DeviceConfig.getProperties("{namespace}");

            {{- for flag in flag_elements }}
            {{- if flag.is_read_write }}
            {flag.method_name} =
                properties.getBoolean("{flag.device_config_flag}", {flag.default_value});
            {{- endif- }}
            {{ endfor }}
        } catch (NullPointerException e) \{
        } catch (NullPointerException e) \{
            throw new RuntimeException(
            throw new RuntimeException(
                "Cannot read value of flag " + flagName + " from DeviceConfig. "
                "Cannot read value from namespace {namespace} "
                + "It could be that the code using flag executed "
                + "from DeviceConfig. It could be that the code using flag "
                + "before SettingsProvider initialization. "
                + "executed before SettingsProvider initialization. Please use "
                + "Please use fixed read-only flag by adding "
                + "fixed read-only flag by adding is_fixed_read_only: true in "
                + "is_fixed_read_only: true in flag declaration.",
                + "flag declaration.",
                e
                e
            );
            );
        }
        }
        {namespace}_is_cached = true;
    }
{{ endfor- }}
{{ endif- }}


        return properties;
{{ for flag in flag_elements }}
    @Override
    @UnsupportedAppUsage
    public boolean {flag.method_name}() \{
    {{ -if flag.is_read_write }}
        if (!{flag.device_config_namespace}_is_cached) \{
            load_overrides_{flag.device_config_namespace}();
        }
        }
        return {flag.method_name};
    {{ else }}
        return {flag.default_value};
    {{ endif- }}
    {{ endif- }}
    }
    }
{{ endfor }}
}
{{ else }}
{{ else }}
{#- Generate only stub if in test mode #}
{#- Generate only stub if in test mode #}
/** @hide */
/** @hide */
@@ -70,6 +71,6 @@ public final class FeatureFlagsImpl implements FeatureFlags \{
        throw new UnsupportedOperationException(
        throw new UnsupportedOperationException(
            "Method is not implemented.");
            "Method is not implemented.");
    }
    }
{{ endfor }}
{{ endfor- }}
}
}
{{ endif }}
{{ endif }}