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

Commit 99b189ac authored by Ted Bauer's avatar Ted Bauer Committed by Gerrit Code Review
Browse files

Merge "Cache Java codegen'd flags in static member variables." into main

parents 136fa83d afe55106
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -58,6 +58,7 @@ rust_defaults {
        "libaconfig_protos",
        "libanyhow",
        "libclap",
        "libitertools",
        "libprotobuf",
        "libserde",
        "libserde_json",
+1 −0
Original line number Diff line number Diff line
@@ -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"] }
+39 −41
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@
 */

use anyhow::Result;
use itertools::Itertools;
use serde::Serialize;
use std::collections::BTreeSet;
use std::path::PathBuf;
@@ -34,12 +35,18 @@ where
{
    let flag_elements: Vec<FlagElement> =
        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> =
        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_set,
        is_test_mode,
        is_read_write,
        properties_set,
@@ -75,6 +82,7 @@ where
#[derive(Serialize)]
struct Context {
    pub flag_elements: Vec<FlagElement>,
    pub namespace_set: BTreeSet<String>,
    pub is_test_mode: bool,
    pub is_read_write: bool,
    pub properties_set: BTreeSet<String>,
@@ -289,7 +297,31 @@ 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 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
            @UnsupportedAppUsage
            public boolean disabledRo() {
@@ -298,18 +330,10 @@ 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
@@ -324,36 +348,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;
            }
        }
        "#;
+38 −37
Original line number Diff line number Diff line
@@ -8,57 +8,58 @@ 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- }}
{{- if is_read_write }}
{{- for namespace in namespace_set }}
    private static boolean {namespace}_is_cached = false;
{{- endfor- }}

{{ for flag in flag_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}
                );
    {{ else }}
        return {flag.default_value};
    {{ endif- }}
    }
    private static boolean {flag.method_name} = {flag.default_value};
{{- endif- }}
{{ endfor }}

{{ -if is_read_write }}
    private Properties getProperties(
            String namespace,
            String flagName) \{
        Properties properties = null;
{{ for namespace in namespace_set }}
    private void load_overrides_{namespace}() \{
        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) \{
            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 from namespace {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
            );
        }
        {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- }}
    }
{{ endfor }}
}
{{ else }}
{#- Generate only stub if in test mode #}
/** @hide */
@@ -70,6 +71,6 @@ public final class FeatureFlagsImpl implements FeatureFlags \{
        throw new UnsupportedOperationException(
            "Method is not implemented.");
    }
{{ endfor }}
{{ endfor- }}
}
{{ endif }}