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

Original change: https://android-review.googlesource.com/c/platform/build/+/2827710

Change-Id: Ic4270c66a7baa9ba90869f5dc72b8d4b48bfdd54
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Ted Bauer
2023-11-14 19:43:41 +00:00
committed by Automerger Merge Worker
4 changed files with 79 additions and 78 deletions

View File

@@ -58,6 +58,7 @@ rust_defaults {
"libaconfig_protos",
"libanyhow",
"libclap",
"libitertools",
"libprotobuf",
"libserde",
"libserde_json",

View File

@@ -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"] }

View File

@@ -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"
);
if (!aconfig_test_is_cached) {
load_overrides_aconfig_test();
}
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;
}
}
"#;

View File

@@ -8,10 +8,41 @@ 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};
{{- if is_read_write }}
{{- for namespace in namespace_set }}
private static boolean {namespace}_is_cached = false;
{{- endfor- }}
{{ for flag in flag_elements }}
{{- if flag.is_read_write }}
private static boolean {flag.method_name} = {flag.default_value};
{{- endif- }}
{{ endfor }}
{{ for namespace in namespace_set }}
private void load_overrides_{namespace}() \{
try \{
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 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- }}
{{ for flag in flag_elements }}
@@ -19,45 +50,15 @@ public final class FeatureFlagsImpl implements FeatureFlags \{
@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}"
);
if (!{flag.device_config_namespace}_is_cached) \{
load_overrides_{flag.device_config_namespace}();
}
return {flag.properties}
.getBoolean(
"{flag.device_config_flag}",
{flag.default_value}
);
return {flag.method_name};
{{ else }}
return {flag.default_value};
{{ endif- }}
}
{{ endfor }}
{{ -if is_read_write }}
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;
}
{{ endif- }}
}
{{ else }}
{#- Generate only stub if in test mode #}
@@ -70,6 +71,6 @@ public final class FeatureFlagsImpl implements FeatureFlags \{
throw new UnsupportedOperationException(
"Method is not implemented.");
}
{{ endfor }}
{{ endfor- }}
}
{{ endif }}