Merge "Revert^2 "Cache Java codegen'd flags in static member variables."" into main
This commit is contained in:
commit
ca355c09a2
10 changed files with 305 additions and 90 deletions
|
@ -58,6 +58,7 @@ rust_defaults {
|
|||
"libaconfig_protos",
|
||||
"libanyhow",
|
||||
"libclap",
|
||||
"libitertools",
|
||||
"libprotobuf",
|
||||
"libserde",
|
||||
"libserde_json",
|
||||
|
|
|
@ -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"] }
|
||||
|
|
|
@ -32,8 +32,9 @@ where
|
|||
I: Iterator<Item = &'a ProtoParsedFlag>,
|
||||
{
|
||||
let mut readwrite_count = 0;
|
||||
let class_elements: Vec<ClassElement> =
|
||||
parsed_flags_iter.map(|pf| create_class_element(package, pf, &mut readwrite_count)).collect();
|
||||
let class_elements: Vec<ClassElement> = parsed_flags_iter
|
||||
.map(|pf| create_class_element(package, pf, &mut readwrite_count))
|
||||
.collect();
|
||||
let readwrite = readwrite_count > 0;
|
||||
let has_fixed_read_only = class_elements.iter().any(|item| item.is_fixed_read_only);
|
||||
let header = package.replace('.', "_");
|
||||
|
@ -110,7 +111,9 @@ pub struct ClassElement {
|
|||
fn create_class_element(package: &str, pf: &ProtoParsedFlag, rw_count: &mut i32) -> ClassElement {
|
||||
ClassElement {
|
||||
readwrite_idx: if pf.permission() == ProtoFlagPermission::READ_WRITE {
|
||||
let index = *rw_count; *rw_count += 1; index
|
||||
let index = *rw_count;
|
||||
*rw_count += 1;
|
||||
index
|
||||
} else {
|
||||
-1
|
||||
},
|
||||
|
@ -162,6 +165,8 @@ public:
|
|||
|
||||
virtual bool disabled_rw() = 0;
|
||||
|
||||
virtual bool disabled_rw_2() = 0;
|
||||
|
||||
virtual bool enabled_fixed_ro() = 0;
|
||||
|
||||
virtual bool enabled_ro() = 0;
|
||||
|
@ -179,6 +184,10 @@ inline bool disabled_rw() {
|
|||
return provider_->disabled_rw();
|
||||
}
|
||||
|
||||
inline bool disabled_rw_2() {
|
||||
return provider_->disabled_rw_2();
|
||||
}
|
||||
|
||||
inline bool enabled_fixed_ro() {
|
||||
return COM_ANDROID_ACONFIG_TEST_ENABLED_FIXED_RO;
|
||||
}
|
||||
|
@ -200,6 +209,8 @@ bool com_android_aconfig_test_disabled_ro();
|
|||
|
||||
bool com_android_aconfig_test_disabled_rw();
|
||||
|
||||
bool com_android_aconfig_test_disabled_rw_2();
|
||||
|
||||
bool com_android_aconfig_test_enabled_fixed_ro();
|
||||
|
||||
bool com_android_aconfig_test_enabled_ro();
|
||||
|
@ -233,6 +244,10 @@ public:
|
|||
|
||||
virtual void disabled_rw(bool val) = 0;
|
||||
|
||||
virtual bool disabled_rw_2() = 0;
|
||||
|
||||
virtual void disabled_rw_2(bool val) = 0;
|
||||
|
||||
virtual bool enabled_fixed_ro() = 0;
|
||||
|
||||
virtual void enabled_fixed_ro(bool val) = 0;
|
||||
|
@ -266,6 +281,14 @@ inline void disabled_rw(bool val) {
|
|||
provider_->disabled_rw(val);
|
||||
}
|
||||
|
||||
inline bool disabled_rw_2() {
|
||||
return provider_->disabled_rw_2();
|
||||
}
|
||||
|
||||
inline void disabled_rw_2(bool val) {
|
||||
provider_->disabled_rw_2(val);
|
||||
}
|
||||
|
||||
inline bool enabled_fixed_ro() {
|
||||
return provider_->enabled_fixed_ro();
|
||||
}
|
||||
|
@ -307,6 +330,10 @@ bool com_android_aconfig_test_disabled_rw();
|
|||
|
||||
void set_com_android_aconfig_test_disabled_rw(bool val);
|
||||
|
||||
bool com_android_aconfig_test_disabled_rw_2();
|
||||
|
||||
void set_com_android_aconfig_test_disabled_rw_2(bool val);
|
||||
|
||||
bool com_android_aconfig_test_enabled_fixed_ro();
|
||||
|
||||
void set_com_android_aconfig_test_enabled_fixed_ro(bool val);
|
||||
|
@ -352,6 +379,16 @@ namespace com::android::aconfig::test {
|
|||
return cache_[0];
|
||||
}
|
||||
|
||||
virtual bool disabled_rw_2() override {
|
||||
if (cache_[1] == -1) {
|
||||
cache_[1] = server_configurable_flags::GetServerConfigurableFlag(
|
||||
"aconfig_flags.other_namespace",
|
||||
"com.android.aconfig.test.disabled_rw_2",
|
||||
"false") == "true";
|
||||
}
|
||||
return cache_[1];
|
||||
}
|
||||
|
||||
virtual bool enabled_fixed_ro() override {
|
||||
return COM_ANDROID_ACONFIG_TEST_ENABLED_FIXED_RO;
|
||||
}
|
||||
|
@ -361,18 +398,18 @@ namespace com::android::aconfig::test {
|
|||
}
|
||||
|
||||
virtual bool enabled_rw() override {
|
||||
if (cache_[1] == -1) {
|
||||
cache_[1] = server_configurable_flags::GetServerConfigurableFlag(
|
||||
if (cache_[2] == -1) {
|
||||
cache_[2] = server_configurable_flags::GetServerConfigurableFlag(
|
||||
"aconfig_flags.aconfig_test",
|
||||
"com.android.aconfig.test.enabled_rw",
|
||||
"true") == "true";
|
||||
}
|
||||
return cache_[1];
|
||||
return cache_[2];
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
std::vector<int8_t> cache_ = std::vector<int8_t>(2, -1);
|
||||
std::vector<int8_t> cache_ = std::vector<int8_t>(3, -1);
|
||||
|
||||
std::unique_ptr<flag_provider_interface> provider_ =
|
||||
std::make_unique<flag_provider>();
|
||||
|
@ -386,6 +423,10 @@ bool com_android_aconfig_test_disabled_rw() {
|
|||
return com::android::aconfig::test::disabled_rw();
|
||||
}
|
||||
|
||||
bool com_android_aconfig_test_disabled_rw_2() {
|
||||
return com::android::aconfig::test::disabled_rw_2();
|
||||
}
|
||||
|
||||
bool com_android_aconfig_test_enabled_fixed_ro() {
|
||||
return COM_ANDROID_ACONFIG_TEST_ENABLED_FIXED_RO;
|
||||
}
|
||||
|
@ -446,6 +487,22 @@ namespace com::android::aconfig::test {
|
|||
overrides_["disabled_rw"] = val;
|
||||
}
|
||||
|
||||
virtual bool disabled_rw_2() override {
|
||||
auto it = overrides_.find("disabled_rw_2");
|
||||
if (it != overrides_.end()) {
|
||||
return it->second;
|
||||
} else {
|
||||
return server_configurable_flags::GetServerConfigurableFlag(
|
||||
"aconfig_flags.other_namespace",
|
||||
"com.android.aconfig.test.disabled_rw_2",
|
||||
"false") == "true";
|
||||
}
|
||||
}
|
||||
|
||||
virtual void disabled_rw_2(bool val) override {
|
||||
overrides_["disabled_rw_2"] = val;
|
||||
}
|
||||
|
||||
virtual bool enabled_fixed_ro() override {
|
||||
auto it = overrides_.find("enabled_fixed_ro");
|
||||
if (it != overrides_.end()) {
|
||||
|
@ -515,6 +572,15 @@ void set_com_android_aconfig_test_disabled_rw(bool val) {
|
|||
com::android::aconfig::test::disabled_rw(val);
|
||||
}
|
||||
|
||||
bool com_android_aconfig_test_disabled_rw_2() {
|
||||
return com::android::aconfig::test::disabled_rw_2();
|
||||
}
|
||||
|
||||
|
||||
void set_com_android_aconfig_test_disabled_rw_2(bool val) {
|
||||
com::android::aconfig::test::disabled_rw_2(val);
|
||||
}
|
||||
|
||||
|
||||
bool com_android_aconfig_test_enabled_fixed_ro() {
|
||||
return com::android::aconfig::test::enabled_fixed_ro();
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
use anyhow::Result;
|
||||
use serde::Serialize;
|
||||
use std::collections::BTreeSet;
|
||||
use std::collections::{BTreeMap, BTreeSet};
|
||||
use std::path::PathBuf;
|
||||
use tinytemplate::TinyTemplate;
|
||||
|
||||
|
@ -34,12 +34,14 @@ where
|
|||
{
|
||||
let flag_elements: Vec<FlagElement> =
|
||||
parsed_flags_iter.map(|pf| create_flag_element(package, pf)).collect();
|
||||
let namespace_flags = gen_flags_by_namespace(&flag_elements);
|
||||
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_flags,
|
||||
is_test_mode,
|
||||
is_read_write,
|
||||
properties_set,
|
||||
|
@ -72,16 +74,44 @@ where
|
|||
.collect::<Result<Vec<OutputFile>>>()
|
||||
}
|
||||
|
||||
fn gen_flags_by_namespace(flags: &[FlagElement]) -> Vec<NamespaceFlags> {
|
||||
let mut namespace_to_flag: BTreeMap<String, Vec<FlagElement>> = BTreeMap::new();
|
||||
|
||||
for flag in flags {
|
||||
match namespace_to_flag.get_mut(&flag.device_config_namespace) {
|
||||
Some(flag_list) => flag_list.push(flag.clone()),
|
||||
None => {
|
||||
namespace_to_flag.insert(flag.device_config_namespace.clone(), vec![flag.clone()]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace_to_flag
|
||||
.iter()
|
||||
.map(|(namespace, flags)| NamespaceFlags {
|
||||
namespace: namespace.to_string(),
|
||||
flags: flags.clone(),
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
struct Context {
|
||||
pub flag_elements: Vec<FlagElement>,
|
||||
pub namespace_flags: Vec<NamespaceFlags>,
|
||||
pub is_test_mode: bool,
|
||||
pub is_read_write: bool,
|
||||
pub properties_set: BTreeSet<String>,
|
||||
pub package_name: String,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[derive(Serialize, Debug)]
|
||||
struct NamespaceFlags {
|
||||
pub namespace: String,
|
||||
pub flags: Vec<FlagElement>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Clone, Debug)]
|
||||
struct FlagElement {
|
||||
pub default_value: bool,
|
||||
pub device_config_namespace: String,
|
||||
|
@ -148,6 +178,8 @@ mod tests {
|
|||
boolean disabledRo();
|
||||
@UnsupportedAppUsage
|
||||
boolean disabledRw();
|
||||
@UnsupportedAppUsage
|
||||
boolean disabledRw2();
|
||||
@com.android.aconfig.annotations.AssumeTrueForR8
|
||||
@UnsupportedAppUsage
|
||||
boolean enabledFixedRo();
|
||||
|
@ -170,6 +202,8 @@ mod tests {
|
|||
/** @hide */
|
||||
public static final String FLAG_DISABLED_RW = "com.android.aconfig.test.disabled_rw";
|
||||
/** @hide */
|
||||
public static final String FLAG_DISABLED_RW_2 = "com.android.aconfig.test.disabled_rw_2";
|
||||
/** @hide */
|
||||
public static final String FLAG_ENABLED_FIXED_RO = "com.android.aconfig.test.enabled_fixed_ro";
|
||||
/** @hide */
|
||||
public static final String FLAG_ENABLED_RO = "com.android.aconfig.test.enabled_ro";
|
||||
|
@ -185,6 +219,10 @@ mod tests {
|
|||
public static boolean disabledRw() {
|
||||
return FEATURE_FLAGS.disabledRw();
|
||||
}
|
||||
@UnsupportedAppUsage
|
||||
public static boolean disabledRw2() {
|
||||
return FEATURE_FLAGS.disabledRw2();
|
||||
}
|
||||
@com.android.aconfig.annotations.AssumeTrueForR8
|
||||
@UnsupportedAppUsage
|
||||
public static boolean enabledFixedRo() {
|
||||
|
@ -224,6 +262,11 @@ mod tests {
|
|||
}
|
||||
@Override
|
||||
@UnsupportedAppUsage
|
||||
public boolean disabledRw2() {
|
||||
return getValue(Flags.FLAG_DISABLED_RW_2);
|
||||
}
|
||||
@Override
|
||||
@UnsupportedAppUsage
|
||||
public boolean enabledFixedRo() {
|
||||
return getValue(Flags.FLAG_ENABLED_FIXED_RO);
|
||||
}
|
||||
|
@ -259,6 +302,7 @@ mod tests {
|
|||
Map.ofEntries(
|
||||
Map.entry(Flags.FLAG_DISABLED_RO, false),
|
||||
Map.entry(Flags.FLAG_DISABLED_RW, false),
|
||||
Map.entry(Flags.FLAG_DISABLED_RW_2, false),
|
||||
Map.entry(Flags.FLAG_ENABLED_FIXED_RO, false),
|
||||
Map.entry(Flags.FLAG_ENABLED_RO, false),
|
||||
Map.entry(Flags.FLAG_ENABLED_RW, false)
|
||||
|
@ -289,7 +333,52 @@ 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 other_namespace_is_cached = false;
|
||||
private static boolean disabledRw = false;
|
||||
private static boolean disabledRw2 = 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;
|
||||
}
|
||||
|
||||
private void load_overrides_other_namespace() {
|
||||
try {
|
||||
Properties properties = DeviceConfig.getProperties("other_namespace");
|
||||
disabledRw2 =
|
||||
properties.getBoolean("com.android.aconfig.test.disabled_rw_2", false);
|
||||
} catch (NullPointerException e) {
|
||||
throw new RuntimeException(
|
||||
"Cannot read value from namespace other_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
|
||||
);
|
||||
}
|
||||
other_namespace_is_cached = true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@UnsupportedAppUsage
|
||||
public boolean disabledRo() {
|
||||
|
@ -298,18 +387,18 @@ 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
|
||||
public boolean disabledRw2() {
|
||||
if (!other_namespace_is_cached) {
|
||||
load_overrides_other_namespace();
|
||||
}
|
||||
return disabledRw2;
|
||||
}
|
||||
@Override
|
||||
@UnsupportedAppUsage
|
||||
|
@ -324,36 +413,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;
|
||||
}
|
||||
}
|
||||
"#;
|
||||
|
@ -426,6 +489,12 @@ mod tests {
|
|||
}
|
||||
@Override
|
||||
@UnsupportedAppUsage
|
||||
public boolean disabledRw2() {
|
||||
throw new UnsupportedOperationException(
|
||||
"Method is not implemented.");
|
||||
}
|
||||
@Override
|
||||
@UnsupportedAppUsage
|
||||
public boolean enabledFixedRo() {
|
||||
throw new UnsupportedOperationException(
|
||||
"Method is not implemented.");
|
||||
|
|
|
@ -104,6 +104,12 @@ lazy_static::lazy_static! {
|
|||
"com.android.aconfig.test.disabled_rw",
|
||||
"false") == "true";
|
||||
|
||||
/// flag value cache for disabled_rw_2
|
||||
static ref CACHED_disabled_rw_2: bool = flags_rust::GetServerConfigurableFlag(
|
||||
"aconfig_flags.other_namespace",
|
||||
"com.android.aconfig.test.disabled_rw_2",
|
||||
"false") == "true";
|
||||
|
||||
/// flag value cache for enabled_rw
|
||||
static ref CACHED_enabled_rw: bool = flags_rust::GetServerConfigurableFlag(
|
||||
"aconfig_flags.aconfig_test",
|
||||
|
@ -122,6 +128,11 @@ impl FlagProvider {
|
|||
*CACHED_disabled_rw
|
||||
}
|
||||
|
||||
/// query flag disabled_rw_2
|
||||
pub fn disabled_rw_2(&self) -> bool {
|
||||
*CACHED_disabled_rw_2
|
||||
}
|
||||
|
||||
/// query flag enabled_fixed_ro
|
||||
pub fn enabled_fixed_ro(&self) -> bool {
|
||||
true
|
||||
|
@ -153,6 +164,12 @@ pub fn disabled_rw() -> bool {
|
|||
PROVIDER.disabled_rw()
|
||||
}
|
||||
|
||||
/// query flag disabled_rw_2
|
||||
#[inline(always)]
|
||||
pub fn disabled_rw_2() -> bool {
|
||||
PROVIDER.disabled_rw_2()
|
||||
}
|
||||
|
||||
/// query flag enabled_fixed_ro
|
||||
#[inline(always)]
|
||||
pub fn enabled_fixed_ro() -> bool {
|
||||
|
@ -211,6 +228,21 @@ impl FlagProvider {
|
|||
self.overrides.insert("disabled_rw", val);
|
||||
}
|
||||
|
||||
/// query flag disabled_rw_2
|
||||
pub fn disabled_rw_2(&self) -> bool {
|
||||
self.overrides.get("disabled_rw_2").copied().unwrap_or(
|
||||
flags_rust::GetServerConfigurableFlag(
|
||||
"aconfig_flags.other_namespace",
|
||||
"com.android.aconfig.test.disabled_rw_2",
|
||||
"false") == "true"
|
||||
)
|
||||
}
|
||||
|
||||
/// set flag disabled_rw_2
|
||||
pub fn set_disabled_rw_2(&mut self, val: bool) {
|
||||
self.overrides.insert("disabled_rw_2", val);
|
||||
}
|
||||
|
||||
/// query flag enabled_fixed_ro
|
||||
pub fn enabled_fixed_ro(&self) -> bool {
|
||||
self.overrides.get("enabled_fixed_ro").copied().unwrap_or(
|
||||
|
@ -285,6 +317,18 @@ pub fn set_disabled_rw(val: bool) {
|
|||
PROVIDER.lock().unwrap().set_disabled_rw(val);
|
||||
}
|
||||
|
||||
/// query flag disabled_rw_2
|
||||
#[inline(always)]
|
||||
pub fn disabled_rw_2() -> bool {
|
||||
PROVIDER.lock().unwrap().disabled_rw_2()
|
||||
}
|
||||
|
||||
/// set flag disabled_rw_2
|
||||
#[inline(always)]
|
||||
pub fn set_disabled_rw_2(val: bool) {
|
||||
PROVIDER.lock().unwrap().set_disabled_rw_2(val);
|
||||
}
|
||||
|
||||
/// query flag enabled_fixed_ro
|
||||
#[inline(always)]
|
||||
pub fn enabled_fixed_ro() -> bool {
|
||||
|
|
|
@ -334,7 +334,7 @@ mod tests {
|
|||
assert_eq!(ProtoFlagState::ENABLED, enabled_ro.trace[2].state());
|
||||
assert_eq!(ProtoFlagPermission::READ_ONLY, enabled_ro.trace[2].permission());
|
||||
|
||||
assert_eq!(5, parsed_flags.parsed_flag.len());
|
||||
assert_eq!(6, parsed_flags.parsed_flag.len());
|
||||
for pf in parsed_flags.parsed_flag.iter() {
|
||||
if pf.name() == "enabled_fixed_ro" {
|
||||
continue;
|
||||
|
@ -433,7 +433,7 @@ mod tests {
|
|||
let input = parse_test_flags_as_input();
|
||||
let bytes = create_device_config_defaults(input).unwrap();
|
||||
let text = std::str::from_utf8(&bytes).unwrap();
|
||||
assert_eq!("aconfig_test:com.android.aconfig.test.disabled_rw=disabled\naconfig_test:com.android.aconfig.test.enabled_rw=enabled\n", text);
|
||||
assert_eq!("aconfig_test:com.android.aconfig.test.disabled_rw=disabled\nother_namespace:com.android.aconfig.test.disabled_rw_2=disabled\naconfig_test:com.android.aconfig.test.enabled_rw=enabled\n", text);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -441,7 +441,7 @@ mod tests {
|
|||
let input = parse_test_flags_as_input();
|
||||
let bytes = create_device_config_sysprops(input).unwrap();
|
||||
let text = std::str::from_utf8(&bytes).unwrap();
|
||||
assert_eq!("persist.device_config.com.android.aconfig.test.disabled_rw=false\npersist.device_config.com.android.aconfig.test.enabled_rw=true\n", text);
|
||||
assert_eq!("persist.device_config.com.android.aconfig.test.disabled_rw=false\npersist.device_config.com.android.aconfig.test.disabled_rw_2=false\npersist.device_config.com.android.aconfig.test.enabled_rw=true\n", text);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -58,6 +58,26 @@ parsed_flag {
|
|||
}
|
||||
is_fixed_read_only: false
|
||||
}
|
||||
parsed_flag {
|
||||
package: "com.android.aconfig.test"
|
||||
name: "disabled_rw_2"
|
||||
namespace: "other_namespace"
|
||||
description: "This flag is DISABLED + READ_WRITE"
|
||||
bug: "999"
|
||||
state: DISABLED
|
||||
permission: READ_WRITE
|
||||
trace {
|
||||
source: "tests/test.aconfig"
|
||||
state: DISABLED
|
||||
permission: READ_WRITE
|
||||
}
|
||||
trace {
|
||||
source: "tests/first.values"
|
||||
state: DISABLED
|
||||
permission: READ_WRITE
|
||||
}
|
||||
is_fixed_read_only: false
|
||||
}
|
||||
parsed_flag {
|
||||
package: "com.android.aconfig.test"
|
||||
name: "enabled_fixed_ro"
|
||||
|
|
|
@ -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_with_flags in namespace_flags }}
|
||||
private static boolean {namespace_with_flags.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_with_flags in namespace_flags }}
|
||||
private void load_overrides_{namespace_with_flags.namespace}() \{
|
||||
try \{
|
||||
Properties properties = DeviceConfig.getProperties("{namespace_with_flags.namespace}");
|
||||
|
||||
{{- for flag in namespace_with_flags.flags }}
|
||||
{{- 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_with_flags.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_with_flags.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 }}
|
||||
|
|
|
@ -16,6 +16,12 @@ flag_value {
|
|||
state: ENABLED
|
||||
permission: READ_WRITE
|
||||
}
|
||||
flag_value {
|
||||
package: "com.android.aconfig.test"
|
||||
name: "disabled_rw_2"
|
||||
state: DISABLED
|
||||
permission: READ_WRITE
|
||||
}
|
||||
flag_value {
|
||||
package: "com.android.aconfig.test"
|
||||
name: "enabled_fixed_ro"
|
||||
|
|
|
@ -51,3 +51,10 @@ flag {
|
|||
bug: ""
|
||||
is_fixed_read_only: true
|
||||
}
|
||||
|
||||
flag {
|
||||
name: "disabled_rw_2"
|
||||
namespace: "other_namespace"
|
||||
description: "This flag is DISABLED + READ_WRITE"
|
||||
bug: "999"
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue