Merge "Make new storage and old starge seperate" into main
diff --git a/tools/aconfig/aconfig/src/codegen/java.rs b/tools/aconfig/aconfig/src/codegen/java.rs
index 1ac58c1..a34166d 100644
--- a/tools/aconfig/aconfig/src/codegen/java.rs
+++ b/tools/aconfig/aconfig/src/codegen/java.rs
@@ -137,6 +137,7 @@
pub default_value: bool,
pub device_config_namespace: String,
pub device_config_flag: String,
+ pub flag_name: String,
pub flag_name_constant_suffix: String,
pub flag_offset: u16,
pub is_read_write: bool,
@@ -156,6 +157,7 @@
default_value: pf.state() == ProtoFlagState::ENABLED,
device_config_namespace: pf.namespace().to_string(),
device_config_flag,
+ flag_name: pf.name().to_string(),
flag_name_constant_suffix: pf.name().to_ascii_uppercase(),
flag_offset: *flag_offsets.get(pf.name()).expect("didnt find package offset :("),
is_read_write: pf.permission() == ProtoFlagPermission::READ_WRITE,
@@ -507,97 +509,39 @@
private static FeatureFlags FEATURE_FLAGS = new FeatureFlagsImpl();
}"#;
- let expected_featureflagsmpl_content_0 = r#"
+ let expected_featureflagsmpl_content = r#"
package com.android.aconfig.test;
// TODO(b/303773055): Remove the annotation after access issue is resolved.
import android.compat.annotation.UnsupportedAppUsage;
import android.provider.DeviceConfig;
import android.provider.DeviceConfig.Properties;
- "#;
+ import android.aconfig.storage.StorageInternalReader;
+ import java.nio.file.Files;
+ import java.nio.file.Paths;
- let expected_featureflagsmpl_content_1 = r#"
/** @hide */
public final class FeatureFlagsImpl implements FeatureFlags {
+ private static final boolean isReadFromNew = Files.exists(Paths.get("/metadata/aconfig/boot/enable_only_new_storage"));
+ private static volatile boolean isCached = false;
private static volatile boolean aconfig_test_is_cached = false;
private static volatile boolean other_namespace_is_cached = false;
private static boolean disabledRw = false;
private static boolean disabledRwExported = false;
private static boolean disabledRwInOtherNamespace = false;
private static boolean enabledRw = true;
- "#;
- let expected_featureflagsmpl_content_2 = r#"
- @Override
- @com.android.aconfig.annotations.AconfigFlagAccessor
- @UnsupportedAppUsage
- public boolean disabledRo() {
- return false;
- }
- @Override
- @com.android.aconfig.annotations.AconfigFlagAccessor
- @UnsupportedAppUsage
- public boolean disabledRw() {
- if (!aconfig_test_is_cached) {
- load_overrides_aconfig_test();
+ private void init() {
+ StorageInternalReader reader = null;
+ try {
+ reader = new StorageInternalReader("system", "com.android.aconfig.test");
+ disabledRw = reader.getBooleanFlagValue(1);
+ disabledRwExported = reader.getBooleanFlagValue(2);
+ enabledRw = reader.getBooleanFlagValue(8);
+ disabledRwInOtherNamespace = reader.getBooleanFlagValue(3);
+ } catch (Exception e) {
+ throw new RuntimeException("Cannot read flag in codegen", e);
}
- return disabledRw;
+ isCached = true;
}
- @Override
- @com.android.aconfig.annotations.AconfigFlagAccessor
- @UnsupportedAppUsage
- public boolean disabledRwExported() {
- if (!aconfig_test_is_cached) {
- load_overrides_aconfig_test();
- }
- return disabledRwExported;
- }
- @Override
- @com.android.aconfig.annotations.AconfigFlagAccessor
- @UnsupportedAppUsage
- public boolean disabledRwInOtherNamespace() {
- if (!other_namespace_is_cached) {
- load_overrides_other_namespace();
- }
- return disabledRwInOtherNamespace;
- }
- @Override
- @com.android.aconfig.annotations.AconfigFlagAccessor
- @UnsupportedAppUsage
- public boolean enabledFixedRo() {
- return true;
- }
- @Override
- @com.android.aconfig.annotations.AconfigFlagAccessor
- @UnsupportedAppUsage
- public boolean enabledFixedRoExported() {
- return true;
- }
- @Override
- @com.android.aconfig.annotations.AconfigFlagAccessor
- @UnsupportedAppUsage
- public boolean enabledRo() {
- return true;
- }
- @Override
- @com.android.aconfig.annotations.AconfigFlagAccessor
- @UnsupportedAppUsage
- public boolean enabledRoExported() {
- return true;
- }
- @Override
- @com.android.aconfig.annotations.AconfigFlagAccessor
- @UnsupportedAppUsage
- public boolean enabledRw() {
- if (!aconfig_test_is_cached) {
- load_overrides_aconfig_test();
- }
- return enabledRw;
- }
- }
- "#;
-
- let expect_featureflagsimpl_content_old = expected_featureflagsmpl_content_0.to_owned()
- + expected_featureflagsmpl_content_1
- + r#"
private void load_overrides_aconfig_test() {
try {
Properties properties = DeviceConfig.getProperties("aconfig_test");
@@ -636,188 +580,104 @@
);
}
other_namespace_is_cached = true;
- }"#
- + expected_featureflagsmpl_content_2;
+ }
+
+ @Override
+ @com.android.aconfig.annotations.AconfigFlagAccessor
+ @UnsupportedAppUsage
+ public boolean disabledRo() {
+ return false;
+ }
+ @Override
+ @com.android.aconfig.annotations.AconfigFlagAccessor
+ @UnsupportedAppUsage
+ public boolean disabledRw() {
+ if (isReadFromNew) {
+ if (!isCached) {
+ init();
+ }
+ } else {
+ if (!aconfig_test_is_cached) {
+ load_overrides_aconfig_test();
+ }
+ }
+ return disabledRw;
+ }
+ @Override
+ @com.android.aconfig.annotations.AconfigFlagAccessor
+ @UnsupportedAppUsage
+ public boolean disabledRwExported() {
+ if (isReadFromNew) {
+ if (!isCached) {
+ init();
+ }
+ } else {
+ if (!aconfig_test_is_cached) {
+ load_overrides_aconfig_test();
+ }
+ }
+ return disabledRwExported;
+ }
+ @Override
+ @com.android.aconfig.annotations.AconfigFlagAccessor
+ @UnsupportedAppUsage
+ public boolean disabledRwInOtherNamespace() {
+ if (isReadFromNew) {
+ if (!isCached) {
+ init();
+ }
+ } else {
+ if (!other_namespace_is_cached) {
+ load_overrides_other_namespace();
+ }
+ }
+ return disabledRwInOtherNamespace;
+ }
+ @Override
+ @com.android.aconfig.annotations.AconfigFlagAccessor
+ @UnsupportedAppUsage
+ public boolean enabledFixedRo() {
+ return true;
+ }
+ @Override
+ @com.android.aconfig.annotations.AconfigFlagAccessor
+ @UnsupportedAppUsage
+ public boolean enabledFixedRoExported() {
+ return true;
+ }
+ @Override
+ @com.android.aconfig.annotations.AconfigFlagAccessor
+ @UnsupportedAppUsage
+ public boolean enabledRo() {
+ return true;
+ }
+ @Override
+ @com.android.aconfig.annotations.AconfigFlagAccessor
+ @UnsupportedAppUsage
+ public boolean enabledRoExported() {
+ return true;
+ }
+ @Override
+ @com.android.aconfig.annotations.AconfigFlagAccessor
+ @UnsupportedAppUsage
+ public boolean enabledRw() {
+ if (isReadFromNew) {
+ if (!isCached) {
+ init();
+ }
+ } else {
+ if (!aconfig_test_is_cached) {
+ load_overrides_aconfig_test();
+ }
+ }
+ return enabledRw;
+ }
+ }
+ "#;
let mut file_set = HashMap::from([
("com/android/aconfig/test/Flags.java", expect_flags_content.as_str()),
- (
- "com/android/aconfig/test/FeatureFlagsImpl.java",
- &expect_featureflagsimpl_content_old,
- ),
- ("com/android/aconfig/test/FeatureFlags.java", EXPECTED_FEATUREFLAGS_COMMON_CONTENT),
- (
- "com/android/aconfig/test/CustomFeatureFlags.java",
- EXPECTED_CUSTOMFEATUREFLAGS_CONTENT,
- ),
- (
- "com/android/aconfig/test/FakeFeatureFlagsImpl.java",
- EXPECTED_FAKEFEATUREFLAGSIMPL_CONTENT,
- ),
- ]);
-
- for file in generated_files {
- let file_path = file.path.to_str().unwrap();
- assert!(file_set.contains_key(file_path), "Cannot find {}", file_path);
- assert_eq!(
- None,
- crate::test::first_significant_code_diff(
- file_set.get(file_path).unwrap(),
- &String::from_utf8(file.contents).unwrap()
- ),
- "File {} content is not correct",
- file_path
- );
- file_set.remove(file_path);
- }
-
- assert!(file_set.is_empty());
-
- let parsed_flags = crate::test::parse_test_flags();
- let mode = CodegenMode::Production;
- let modified_parsed_flags =
- crate::commands::modify_parsed_flags_based_on_mode(parsed_flags, mode).unwrap();
- let flag_ids =
- assign_flag_ids(crate::test::TEST_PACKAGE, modified_parsed_flags.iter()).unwrap();
- let generated_files = generate_java_code(
- crate::test::TEST_PACKAGE,
- modified_parsed_flags.into_iter(),
- mode,
- flag_ids,
- true,
- )
- .unwrap();
-
- let expect_featureflagsimpl_content_new = expected_featureflagsmpl_content_0.to_owned()
- + r#"
- import android.aconfig.storage.StorageInternalReader;
- import android.util.Log;
- "#
- + expected_featureflagsmpl_content_1
- + r#"
- StorageInternalReader reader;
- boolean readFromNewStorage;
-
- boolean useNewStorageValueAndDiscardOld = false;
-
- private final static String TAG = "AconfigJavaCodegen";
- private final static String SUCCESS_LOG = "success: %s value matches";
- private final static String MISMATCH_LOG = "error: %s value mismatch, new storage value is %s, old storage value is %s";
- private final static String ERROR_LOG = "error: failed to read flag value";
-
- private void init() {
- if (reader != null) return;
- if (DeviceConfig.getBoolean("core_experiments_team_internal", "com.android.providers.settings.storage_test_mission_1", false)) {
- readFromNewStorage = true;
- try {
- reader = new StorageInternalReader("system", "com.android.aconfig.test");
- } catch (Exception e) {
- reader = null;
- }
- }
-
- useNewStorageValueAndDiscardOld =
- DeviceConfig.getBoolean("core_experiments_team_internal", "com.android.providers.settings.use_new_storage_value", false);
- }
-
- private void load_overrides_aconfig_test() {
- try {
- Properties properties = DeviceConfig.getProperties("aconfig_test");
- disabledRw =
- properties.getBoolean(Flags.FLAG_DISABLED_RW, false);
- disabledRwExported =
- properties.getBoolean(Flags.FLAG_DISABLED_RW_EXPORTED, false);
- enabledRw =
- properties.getBoolean(Flags.FLAG_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;
- init();
- if (readFromNewStorage && reader != null) {
- boolean val;
- try {
- val = reader.getBooleanFlagValue(1);
- if (val != disabledRw) {
- Log.w(TAG, String.format(MISMATCH_LOG, "disabledRw", val, disabledRw));
- }
-
- if (useNewStorageValueAndDiscardOld) {
- disabledRw = val;
- }
-
- val = reader.getBooleanFlagValue(2);
- if (val != disabledRwExported) {
- Log.w(TAG, String.format(MISMATCH_LOG, "disabledRwExported", val, disabledRwExported));
- }
-
- if (useNewStorageValueAndDiscardOld) {
- disabledRwExported = val;
- }
-
- val = reader.getBooleanFlagValue(8);
- if (val != enabledRw) {
- Log.w(TAG, String.format(MISMATCH_LOG, "enabledRw", val, enabledRw));
- }
-
- if (useNewStorageValueAndDiscardOld) {
- enabledRw = val;
- }
-
- } catch (Exception e) {
- Log.e(TAG, ERROR_LOG, e);
- }
- }
- }
-
- private void load_overrides_other_namespace() {
- try {
- Properties properties = DeviceConfig.getProperties("other_namespace");
- disabledRwInOtherNamespace =
- properties.getBoolean(Flags.FLAG_DISABLED_RW_IN_OTHER_NAMESPACE, 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;
- init();
- if (readFromNewStorage && reader != null) {
- boolean val;
- try {
- val = reader.getBooleanFlagValue(3);
- if (val != disabledRwInOtherNamespace) {
- Log.w(TAG, String.format(MISMATCH_LOG, "disabledRwInOtherNamespace", val, disabledRwInOtherNamespace));
- }
-
- if (useNewStorageValueAndDiscardOld) {
- disabledRwInOtherNamespace = val;
- }
-
- } catch (Exception e) {
- Log.e(TAG, ERROR_LOG, e);
- }
- }
- }"# + expected_featureflagsmpl_content_2;
-
- let mut file_set = HashMap::from([
- ("com/android/aconfig/test/Flags.java", expect_flags_content.as_str()),
- (
- "com/android/aconfig/test/FeatureFlagsImpl.java",
- &expect_featureflagsimpl_content_new,
- ),
+ ("com/android/aconfig/test/FeatureFlagsImpl.java", expected_featureflagsmpl_content),
("com/android/aconfig/test/FeatureFlags.java", EXPECTED_FEATUREFLAGS_COMMON_CONTENT),
(
"com/android/aconfig/test/CustomFeatureFlags.java",
@@ -908,7 +768,6 @@
private static boolean enabledFixedRoExported = false;
private static boolean enabledRoExported = false;
-
private void load_overrides_aconfig_test() {
try {
Properties properties = DeviceConfig.getProperties("aconfig_test");
@@ -933,21 +792,21 @@
@Override
public boolean disabledRwExported() {
if (!aconfig_test_is_cached) {
- load_overrides_aconfig_test();
+ load_overrides_aconfig_test();
}
return disabledRwExported;
}
@Override
public boolean enabledFixedRoExported() {
if (!aconfig_test_is_cached) {
- load_overrides_aconfig_test();
+ load_overrides_aconfig_test();
}
return enabledFixedRoExported;
}
@Override
public boolean enabledRoExported() {
if (!aconfig_test_is_cached) {
- load_overrides_aconfig_test();
+ load_overrides_aconfig_test();
}
return enabledRoExported;
}
diff --git a/tools/aconfig/aconfig/templates/FeatureFlagsImpl.java.template b/tools/aconfig/aconfig/templates/FeatureFlagsImpl.java.template
index bc01aa4..d1cf191 100644
--- a/tools/aconfig/aconfig/templates/FeatureFlagsImpl.java.template
+++ b/tools/aconfig/aconfig/templates/FeatureFlagsImpl.java.template
@@ -9,56 +9,50 @@
import android.provider.DeviceConfig;
import android.provider.DeviceConfig.Properties;
-
{{ -if not library_exported }}
-{{ -if allow_instrumentation }}
import android.aconfig.storage.StorageInternalReader;
-import android.util.Log;
-{{ -endif }}
+import java.nio.file.Files;
+import java.nio.file.Paths;
{{ -endif }}
{{ -endif }}
/** @hide */
public final class FeatureFlagsImpl implements FeatureFlags \{
{{ -if runtime_lookup_required }}
+{{ -if not library_exported }}
+ private static final boolean isReadFromNew = Files.exists(Paths.get("/metadata/aconfig/boot/enable_only_new_storage"));
+ private static volatile boolean isCached = false;
+{{ -endif }}
{{ -for namespace_with_flags in namespace_flags }}
private static volatile boolean {namespace_with_flags.namespace}_is_cached = false;
{{ -endfor- }}
{{ for flag in flag_elements }}
-{{- if flag.is_read_write }}
+{{ -if flag.is_read_write }}
private static boolean {flag.method_name} = {flag.default_value};
{{ -endif }}
{{ -endfor }}
-{{ -if not library_exported }}
-{{ -if allow_instrumentation }}
- StorageInternalReader reader;
- boolean readFromNewStorage;
- boolean useNewStorageValueAndDiscardOld = false;
-
- private final static String TAG = "AconfigJavaCodegen";
- private final static String SUCCESS_LOG = "success: %s value matches";
- private final static String MISMATCH_LOG = "error: %s value mismatch, new storage value is %s, old storage value is %s";
- private final static String ERROR_LOG = "error: failed to read flag value";
-
+{{ if not library_exported }}
private void init() \{
- if (reader != null) return;
- if (DeviceConfig.getBoolean("core_experiments_team_internal", "com.android.providers.settings.storage_test_mission_1", false)) \{
- readFromNewStorage = true;
- try \{
- reader = new StorageInternalReader("{container}", "{package_name}");
- } catch (Exception e) \{
- reader = null;
- }
+ StorageInternalReader reader = null;
+ try \{
+ reader = new StorageInternalReader("{container}", "{package_name}");
+{{ for namespace_with_flags in namespace_flags }}
+{{ -for flag in namespace_with_flags.flags }}
+{{ if flag.is_read_write }}
+ {flag.method_name} = reader.getBooleanFlagValue({flag.flag_offset});
+{{ endif }}
+{{ -endfor }}
+{{ -endfor }}
+ } catch (Exception e) \{
+ throw new RuntimeException("Cannot read flag in codegen", e);
}
-
- useNewStorageValueAndDiscardOld =
- DeviceConfig.getBoolean("core_experiments_team_internal", "com.android.providers.settings.use_new_storage_value", false);
+ isCached = true;
}
+{{ endif }}
-{{ -endif }}
-{{ -endif }}
+
{{ for namespace_with_flags in namespace_flags }}
private void load_overrides_{namespace_with_flags.namespace}() \{
try \{
@@ -80,34 +74,9 @@
);
}
{namespace_with_flags.namespace}_is_cached = true;
-{{ -if not library_exported }}
-{{ -if allow_instrumentation }}
- init();
- if (readFromNewStorage && reader != null) \{
- boolean val;
- try \{
-{{ -for flag in namespace_with_flags.flags }}
-{{ -if flag.is_read_write }}
-
- val = reader.getBooleanFlagValue({flag.flag_offset});
- if (val != {flag.method_name}) \{
- Log.w(TAG, String.format(MISMATCH_LOG, "{flag.method_name}", val, {flag.method_name}));
- }
-
- if (useNewStorageValueAndDiscardOld) \{
- {flag.method_name} = val;
- }
-
-{{ -endif }}
-{{ -endfor }}
- } catch (Exception e) \{
- Log.e(TAG, ERROR_LOG, e);
- }
- }
-{{ -endif }}
-{{ -endif }}
}
{{ endfor- }}
+
{{ -endif }}{#- end of runtime_lookup_required #}
{{ -for flag in flag_elements }}
@Override
@@ -116,19 +85,31 @@
@UnsupportedAppUsage
{{ -endif }}
public boolean {flag.method_name}() \{
+{{ -if not library_exported }}
{{ -if flag.is_read_write }}
- if (!{flag.device_config_namespace}_is_cached) \{
- load_overrides_{flag.device_config_namespace}();
+ if (isReadFromNew) \{
+ if (!isCached) \{
+ init();
+ }
+ } else \{
+ if (!{flag.device_config_namespace}_is_cached) \{
+ load_overrides_{flag.device_config_namespace}();
+ }
}
return {flag.method_name};
{{ -else }}
return {flag.default_value};
{{ -endif }}
+{{ else }}
+ if (!{flag.device_config_namespace}_is_cached) \{
+ load_overrides_{flag.device_config_namespace}();
+ }
+ return {flag.method_name};
+{{ -endif }}
}
{{ endfor }}
}
-{{ else }}
-{#- Generate only stub if in test mode #}
+{{ else }} {#- Generate only stub if in test mode #}
/** @hide */
public final class FeatureFlagsImpl implements FeatureFlags \{
{{ for flag in flag_elements }}