Merge "Revert^2 "Cache Java codegen'd flags in static member variables."" into main
This commit is contained in:
@@ -58,6 +58,7 @@ rust_defaults {
|
|||||||
"libaconfig_protos",
|
"libaconfig_protos",
|
||||||
"libanyhow",
|
"libanyhow",
|
||||||
"libclap",
|
"libclap",
|
||||||
|
"libitertools",
|
||||||
"libprotobuf",
|
"libprotobuf",
|
||||||
"libserde",
|
"libserde",
|
||||||
"libserde_json",
|
"libserde_json",
|
||||||
|
@@ -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"] }
|
||||||
|
@@ -32,8 +32,9 @@ where
|
|||||||
I: Iterator<Item = &'a ProtoParsedFlag>,
|
I: Iterator<Item = &'a ProtoParsedFlag>,
|
||||||
{
|
{
|
||||||
let mut readwrite_count = 0;
|
let mut readwrite_count = 0;
|
||||||
let class_elements: Vec<ClassElement> =
|
let class_elements: Vec<ClassElement> = parsed_flags_iter
|
||||||
parsed_flags_iter.map(|pf| create_class_element(package, pf, &mut readwrite_count)).collect();
|
.map(|pf| create_class_element(package, pf, &mut readwrite_count))
|
||||||
|
.collect();
|
||||||
let readwrite = readwrite_count > 0;
|
let readwrite = readwrite_count > 0;
|
||||||
let has_fixed_read_only = class_elements.iter().any(|item| item.is_fixed_read_only);
|
let has_fixed_read_only = class_elements.iter().any(|item| item.is_fixed_read_only);
|
||||||
let header = package.replace('.', "_");
|
let header = package.replace('.', "_");
|
||||||
@@ -110,7 +111,9 @@ pub struct ClassElement {
|
|||||||
fn create_class_element(package: &str, pf: &ProtoParsedFlag, rw_count: &mut i32) -> ClassElement {
|
fn create_class_element(package: &str, pf: &ProtoParsedFlag, rw_count: &mut i32) -> ClassElement {
|
||||||
ClassElement {
|
ClassElement {
|
||||||
readwrite_idx: if pf.permission() == ProtoFlagPermission::READ_WRITE {
|
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 {
|
} else {
|
||||||
-1
|
-1
|
||||||
},
|
},
|
||||||
@@ -162,6 +165,8 @@ public:
|
|||||||
|
|
||||||
virtual bool disabled_rw() = 0;
|
virtual bool disabled_rw() = 0;
|
||||||
|
|
||||||
|
virtual bool disabled_rw_2() = 0;
|
||||||
|
|
||||||
virtual bool enabled_fixed_ro() = 0;
|
virtual bool enabled_fixed_ro() = 0;
|
||||||
|
|
||||||
virtual bool enabled_ro() = 0;
|
virtual bool enabled_ro() = 0;
|
||||||
@@ -179,6 +184,10 @@ inline bool disabled_rw() {
|
|||||||
return provider_->disabled_rw();
|
return provider_->disabled_rw();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool disabled_rw_2() {
|
||||||
|
return provider_->disabled_rw_2();
|
||||||
|
}
|
||||||
|
|
||||||
inline bool enabled_fixed_ro() {
|
inline bool enabled_fixed_ro() {
|
||||||
return COM_ANDROID_ACONFIG_TEST_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();
|
||||||
|
|
||||||
|
bool com_android_aconfig_test_disabled_rw_2();
|
||||||
|
|
||||||
bool com_android_aconfig_test_enabled_fixed_ro();
|
bool com_android_aconfig_test_enabled_fixed_ro();
|
||||||
|
|
||||||
bool com_android_aconfig_test_enabled_ro();
|
bool com_android_aconfig_test_enabled_ro();
|
||||||
@@ -233,6 +244,10 @@ public:
|
|||||||
|
|
||||||
virtual void disabled_rw(bool val) = 0;
|
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 bool enabled_fixed_ro() = 0;
|
||||||
|
|
||||||
virtual void enabled_fixed_ro(bool val) = 0;
|
virtual void enabled_fixed_ro(bool val) = 0;
|
||||||
@@ -266,6 +281,14 @@ inline void disabled_rw(bool val) {
|
|||||||
provider_->disabled_rw(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() {
|
inline bool enabled_fixed_ro() {
|
||||||
return provider_->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);
|
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();
|
bool com_android_aconfig_test_enabled_fixed_ro();
|
||||||
|
|
||||||
void set_com_android_aconfig_test_enabled_fixed_ro(bool val);
|
void set_com_android_aconfig_test_enabled_fixed_ro(bool val);
|
||||||
@@ -352,6 +379,16 @@ namespace com::android::aconfig::test {
|
|||||||
return cache_[0];
|
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 {
|
virtual bool enabled_fixed_ro() override {
|
||||||
return COM_ANDROID_ACONFIG_TEST_ENABLED_FIXED_RO;
|
return COM_ANDROID_ACONFIG_TEST_ENABLED_FIXED_RO;
|
||||||
}
|
}
|
||||||
@@ -361,18 +398,18 @@ namespace com::android::aconfig::test {
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual bool enabled_rw() override {
|
virtual bool enabled_rw() override {
|
||||||
if (cache_[1] == -1) {
|
if (cache_[2] == -1) {
|
||||||
cache_[1] = server_configurable_flags::GetServerConfigurableFlag(
|
cache_[2] = server_configurable_flags::GetServerConfigurableFlag(
|
||||||
"aconfig_flags.aconfig_test",
|
"aconfig_flags.aconfig_test",
|
||||||
"com.android.aconfig.test.enabled_rw",
|
"com.android.aconfig.test.enabled_rw",
|
||||||
"true") == "true";
|
"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::unique_ptr<flag_provider_interface> provider_ =
|
||||||
std::make_unique<flag_provider>();
|
std::make_unique<flag_provider>();
|
||||||
@@ -386,6 +423,10 @@ bool com_android_aconfig_test_disabled_rw() {
|
|||||||
return 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() {
|
bool com_android_aconfig_test_enabled_fixed_ro() {
|
||||||
return 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;
|
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 {
|
virtual bool enabled_fixed_ro() override {
|
||||||
auto it = overrides_.find("enabled_fixed_ro");
|
auto it = overrides_.find("enabled_fixed_ro");
|
||||||
if (it != overrides_.end()) {
|
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);
|
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() {
|
bool com_android_aconfig_test_enabled_fixed_ro() {
|
||||||
return com::android::aconfig::test::enabled_fixed_ro();
|
return com::android::aconfig::test::enabled_fixed_ro();
|
||||||
|
@@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use std::collections::BTreeSet;
|
use std::collections::{BTreeMap, BTreeSet};
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use tinytemplate::TinyTemplate;
|
use tinytemplate::TinyTemplate;
|
||||||
|
|
||||||
@@ -34,12 +34,14 @@ 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_flags = gen_flags_by_namespace(&flag_elements);
|
||||||
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_flags,
|
||||||
is_test_mode,
|
is_test_mode,
|
||||||
is_read_write,
|
is_read_write,
|
||||||
properties_set,
|
properties_set,
|
||||||
@@ -72,16 +74,44 @@ where
|
|||||||
.collect::<Result<Vec<OutputFile>>>()
|
.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)]
|
#[derive(Serialize)]
|
||||||
struct Context {
|
struct Context {
|
||||||
pub flag_elements: Vec<FlagElement>,
|
pub flag_elements: Vec<FlagElement>,
|
||||||
|
pub namespace_flags: Vec<NamespaceFlags>,
|
||||||
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>,
|
||||||
pub package_name: 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 {
|
struct FlagElement {
|
||||||
pub default_value: bool,
|
pub default_value: bool,
|
||||||
pub device_config_namespace: String,
|
pub device_config_namespace: String,
|
||||||
@@ -148,6 +178,8 @@ mod tests {
|
|||||||
boolean disabledRo();
|
boolean disabledRo();
|
||||||
@UnsupportedAppUsage
|
@UnsupportedAppUsage
|
||||||
boolean disabledRw();
|
boolean disabledRw();
|
||||||
|
@UnsupportedAppUsage
|
||||||
|
boolean disabledRw2();
|
||||||
@com.android.aconfig.annotations.AssumeTrueForR8
|
@com.android.aconfig.annotations.AssumeTrueForR8
|
||||||
@UnsupportedAppUsage
|
@UnsupportedAppUsage
|
||||||
boolean enabledFixedRo();
|
boolean enabledFixedRo();
|
||||||
@@ -170,6 +202,8 @@ mod tests {
|
|||||||
/** @hide */
|
/** @hide */
|
||||||
public static final String FLAG_DISABLED_RW = "com.android.aconfig.test.disabled_rw";
|
public static final String FLAG_DISABLED_RW = "com.android.aconfig.test.disabled_rw";
|
||||||
/** @hide */
|
/** @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";
|
public static final String FLAG_ENABLED_FIXED_RO = "com.android.aconfig.test.enabled_fixed_ro";
|
||||||
/** @hide */
|
/** @hide */
|
||||||
public static final String FLAG_ENABLED_RO = "com.android.aconfig.test.enabled_ro";
|
public static final String FLAG_ENABLED_RO = "com.android.aconfig.test.enabled_ro";
|
||||||
@@ -185,6 +219,10 @@ mod tests {
|
|||||||
public static boolean disabledRw() {
|
public static boolean disabledRw() {
|
||||||
return FEATURE_FLAGS.disabledRw();
|
return FEATURE_FLAGS.disabledRw();
|
||||||
}
|
}
|
||||||
|
@UnsupportedAppUsage
|
||||||
|
public static boolean disabledRw2() {
|
||||||
|
return FEATURE_FLAGS.disabledRw2();
|
||||||
|
}
|
||||||
@com.android.aconfig.annotations.AssumeTrueForR8
|
@com.android.aconfig.annotations.AssumeTrueForR8
|
||||||
@UnsupportedAppUsage
|
@UnsupportedAppUsage
|
||||||
public static boolean enabledFixedRo() {
|
public static boolean enabledFixedRo() {
|
||||||
@@ -224,6 +262,11 @@ mod tests {
|
|||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
@UnsupportedAppUsage
|
@UnsupportedAppUsage
|
||||||
|
public boolean disabledRw2() {
|
||||||
|
return getValue(Flags.FLAG_DISABLED_RW_2);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
@UnsupportedAppUsage
|
||||||
public boolean enabledFixedRo() {
|
public boolean enabledFixedRo() {
|
||||||
return getValue(Flags.FLAG_ENABLED_FIXED_RO);
|
return getValue(Flags.FLAG_ENABLED_FIXED_RO);
|
||||||
}
|
}
|
||||||
@@ -259,6 +302,7 @@ mod tests {
|
|||||||
Map.ofEntries(
|
Map.ofEntries(
|
||||||
Map.entry(Flags.FLAG_DISABLED_RO, false),
|
Map.entry(Flags.FLAG_DISABLED_RO, false),
|
||||||
Map.entry(Flags.FLAG_DISABLED_RW, 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_FIXED_RO, false),
|
||||||
Map.entry(Flags.FLAG_ENABLED_RO, false),
|
Map.entry(Flags.FLAG_ENABLED_RO, false),
|
||||||
Map.entry(Flags.FLAG_ENABLED_RW, false)
|
Map.entry(Flags.FLAG_ENABLED_RW, false)
|
||||||
@@ -289,7 +333,52 @@ 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 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
|
@Override
|
||||||
@UnsupportedAppUsage
|
@UnsupportedAppUsage
|
||||||
public boolean disabledRo() {
|
public boolean disabledRo() {
|
||||||
@@ -298,18 +387,18 @@ 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",
|
@Override
|
||||||
false
|
@UnsupportedAppUsage
|
||||||
);
|
public boolean disabledRw2() {
|
||||||
|
if (!other_namespace_is_cached) {
|
||||||
|
load_overrides_other_namespace();
|
||||||
|
}
|
||||||
|
return disabledRw2;
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
@UnsupportedAppUsage
|
@UnsupportedAppUsage
|
||||||
@@ -324,36 +413,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
|
return enabledRw;
|
||||||
.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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"#;
|
"#;
|
||||||
@@ -426,6 +489,12 @@ mod tests {
|
|||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
@UnsupportedAppUsage
|
@UnsupportedAppUsage
|
||||||
|
public boolean disabledRw2() {
|
||||||
|
throw new UnsupportedOperationException(
|
||||||
|
"Method is not implemented.");
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
@UnsupportedAppUsage
|
||||||
public boolean enabledFixedRo() {
|
public boolean enabledFixedRo() {
|
||||||
throw new UnsupportedOperationException(
|
throw new UnsupportedOperationException(
|
||||||
"Method is not implemented.");
|
"Method is not implemented.");
|
||||||
|
@@ -104,6 +104,12 @@ lazy_static::lazy_static! {
|
|||||||
"com.android.aconfig.test.disabled_rw",
|
"com.android.aconfig.test.disabled_rw",
|
||||||
"false") == "true";
|
"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
|
/// flag value cache for enabled_rw
|
||||||
static ref CACHED_enabled_rw: bool = flags_rust::GetServerConfigurableFlag(
|
static ref CACHED_enabled_rw: bool = flags_rust::GetServerConfigurableFlag(
|
||||||
"aconfig_flags.aconfig_test",
|
"aconfig_flags.aconfig_test",
|
||||||
@@ -122,6 +128,11 @@ impl FlagProvider {
|
|||||||
*CACHED_disabled_rw
|
*CACHED_disabled_rw
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// query flag disabled_rw_2
|
||||||
|
pub fn disabled_rw_2(&self) -> bool {
|
||||||
|
*CACHED_disabled_rw_2
|
||||||
|
}
|
||||||
|
|
||||||
/// query flag enabled_fixed_ro
|
/// query flag enabled_fixed_ro
|
||||||
pub fn enabled_fixed_ro(&self) -> bool {
|
pub fn enabled_fixed_ro(&self) -> bool {
|
||||||
true
|
true
|
||||||
@@ -153,6 +164,12 @@ pub fn disabled_rw() -> bool {
|
|||||||
PROVIDER.disabled_rw()
|
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
|
/// query flag enabled_fixed_ro
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn enabled_fixed_ro() -> bool {
|
pub fn enabled_fixed_ro() -> bool {
|
||||||
@@ -211,6 +228,21 @@ impl FlagProvider {
|
|||||||
self.overrides.insert("disabled_rw", val);
|
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
|
/// query flag enabled_fixed_ro
|
||||||
pub fn enabled_fixed_ro(&self) -> bool {
|
pub fn enabled_fixed_ro(&self) -> bool {
|
||||||
self.overrides.get("enabled_fixed_ro").copied().unwrap_or(
|
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);
|
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
|
/// query flag enabled_fixed_ro
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn enabled_fixed_ro() -> bool {
|
pub fn enabled_fixed_ro() -> bool {
|
||||||
|
@@ -334,7 +334,7 @@ mod tests {
|
|||||||
assert_eq!(ProtoFlagState::ENABLED, enabled_ro.trace[2].state());
|
assert_eq!(ProtoFlagState::ENABLED, enabled_ro.trace[2].state());
|
||||||
assert_eq!(ProtoFlagPermission::READ_ONLY, enabled_ro.trace[2].permission());
|
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() {
|
for pf in parsed_flags.parsed_flag.iter() {
|
||||||
if pf.name() == "enabled_fixed_ro" {
|
if pf.name() == "enabled_fixed_ro" {
|
||||||
continue;
|
continue;
|
||||||
@@ -433,7 +433,7 @@ mod tests {
|
|||||||
let input = parse_test_flags_as_input();
|
let input = parse_test_flags_as_input();
|
||||||
let bytes = create_device_config_defaults(input).unwrap();
|
let bytes = create_device_config_defaults(input).unwrap();
|
||||||
let text = std::str::from_utf8(&bytes).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]
|
#[test]
|
||||||
@@ -441,7 +441,7 @@ mod tests {
|
|||||||
let input = parse_test_flags_as_input();
|
let input = parse_test_flags_as_input();
|
||||||
let bytes = create_device_config_sysprops(input).unwrap();
|
let bytes = create_device_config_sysprops(input).unwrap();
|
||||||
let text = std::str::from_utf8(&bytes).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]
|
#[test]
|
||||||
|
@@ -58,6 +58,26 @@ parsed_flag {
|
|||||||
}
|
}
|
||||||
is_fixed_read_only: false
|
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 {
|
parsed_flag {
|
||||||
package: "com.android.aconfig.test"
|
package: "com.android.aconfig.test"
|
||||||
name: "enabled_fixed_ro"
|
name: "enabled_fixed_ro"
|
||||||
|
@@ -8,10 +8,41 @@ 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_with_flags in namespace_flags }}
|
||||||
private Properties {properties};
|
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 }}
|
{{ 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- }}
|
{{ endif- }}
|
||||||
|
|
||||||
{{ for flag in flag_elements }}
|
{{ for flag in flag_elements }}
|
||||||
@@ -19,45 +50,15 @@ public final class FeatureFlagsImpl implements FeatureFlags \{
|
|||||||
@UnsupportedAppUsage
|
@UnsupportedAppUsage
|
||||||
public boolean {flag.method_name}() \{
|
public boolean {flag.method_name}() \{
|
||||||
{{ -if flag.is_read_write }}
|
{{ -if flag.is_read_write }}
|
||||||
if ({flag.properties} == null) \{
|
if (!{flag.device_config_namespace}_is_cached) \{
|
||||||
{flag.properties} =
|
load_overrides_{flag.device_config_namespace}();
|
||||||
getProperties(
|
|
||||||
"{flag.device_config_namespace}",
|
|
||||||
"{flag.device_config_flag}"
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
return {flag.properties}
|
return {flag.method_name};
|
||||||
.getBoolean(
|
|
||||||
"{flag.device_config_flag}",
|
|
||||||
{flag.default_value}
|
|
||||||
);
|
|
||||||
{{ else }}
|
{{ else }}
|
||||||
return {flag.default_value};
|
return {flag.default_value};
|
||||||
{{ endif- }}
|
{{ endif- }}
|
||||||
}
|
}
|
||||||
{{ endfor }}
|
{{ 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 }}
|
{{ else }}
|
||||||
{#- Generate only stub if in test mode #}
|
{#- Generate only stub if in test mode #}
|
||||||
@@ -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 }}
|
||||||
|
@@ -16,6 +16,12 @@ flag_value {
|
|||||||
state: ENABLED
|
state: ENABLED
|
||||||
permission: READ_WRITE
|
permission: READ_WRITE
|
||||||
}
|
}
|
||||||
|
flag_value {
|
||||||
|
package: "com.android.aconfig.test"
|
||||||
|
name: "disabled_rw_2"
|
||||||
|
state: DISABLED
|
||||||
|
permission: READ_WRITE
|
||||||
|
}
|
||||||
flag_value {
|
flag_value {
|
||||||
package: "com.android.aconfig.test"
|
package: "com.android.aconfig.test"
|
||||||
name: "enabled_fixed_ro"
|
name: "enabled_fixed_ro"
|
||||||
|
@@ -51,3 +51,10 @@ flag {
|
|||||||
bug: ""
|
bug: ""
|
||||||
is_fixed_read_only: true
|
is_fixed_read_only: true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
flag {
|
||||||
|
name: "disabled_rw_2"
|
||||||
|
namespace: "other_namespace"
|
||||||
|
description: "This flag is DISABLED + READ_WRITE"
|
||||||
|
bug: "999"
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user