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

Commit fa988f0a authored by Zhi Dou's avatar Zhi Dou
Browse files

add hide and unsupportedadppusage annotation to read library

Test: presubmit
Bug: 349874828
Change-Id: I5b808d87fe7df2ba8a85c8c75ee7baa66ff22d6b
parent 409209f0
Loading
Loading
Loading
Loading
+241 −58
Original line number Diff line number Diff line
@@ -508,12 +508,15 @@ mod tests {
            private static FeatureFlags FEATURE_FLAGS = new FeatureFlagsImpl();
        }"#;

        let expect_featureflagsimpl_content = r#"
        let expected_featureflagsmpl_content_0 = 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;
        "#;

        let expected_featureflagsmpl_content_1 = r#"
        /** @hide */
        public final class FeatureFlagsImpl implements FeatureFlags {
            private static boolean aconfig_test_is_cached = false;
@@ -522,48 +525,8 @@ mod tests {
            private static boolean disabledRwExported = false;
            private static boolean disabledRwInOtherNamespace = false;
            private static boolean enabledRw = true;


            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;
            }

            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;
            }

        "#;
        let expected_featureflagsmpl_content_2 = r#"
            @Override
            @com.android.aconfig.annotations.AconfigFlagAccessor
            @UnsupportedAppUsage
@@ -632,9 +595,229 @@ mod tests {
            }
        }
        "#;

        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");
                    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;
            }

            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;
            }"#
            + 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),
            (
                "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;
            import java.io.File;
            "#
            + expected_featureflagsmpl_content_1
            + r#"
        StorageInternalReader reader;
        boolean readFromNewStorage;

        private final static String TAG = "AconfigJavaCodegen";

        public FeatureFlagsImpl() {
            File file = new File("/metadata/aconfig_test_missions/mission_1");
            if (file.exists()) {
                readFromNewStorage = true;
                try {
                    reader = new StorageInternalReader("system", "com.android.aconfig.test");
                } catch (Exception e) {
                    reader = null;
                }
            }
        }

        private void load_overrides_aconfig_test() {
            try {
                boolean val;
                Properties properties = DeviceConfig.getProperties("aconfig_test");
                disabledRw =
                    properties.getBoolean(Flags.FLAG_DISABLED_RW, false);
                if (readFromNewStorage && reader != null) {
                    try {
                        val = reader.getBooleanFlagValue(1);
                        if (val == disabledRw) {
                            Log.i(TAG, "success: disabledRw value matches");
                        } else {
                            Log.i(TAG, String.format(
                                "error: disabledRw value mismatch, new storage value is %s, old storage value is %s",
                                val, disabledRw));
                        }
                    } catch (Exception e) {
                        Log.e(TAG, "error: failed to read flag value of disabledRw", e);
                    }
                }
                disabledRwExported =
                    properties.getBoolean(Flags.FLAG_DISABLED_RW_EXPORTED, false);
                if (readFromNewStorage && reader != null) {
                    try {
                        val = reader.getBooleanFlagValue(2);
                        if (val == disabledRwExported) {
                            Log.i(TAG, "success: disabledRwExported value matches");
                        } else {
                            Log.i(TAG, String.format(
                                "error: disabledRwExported value mismatch, new storage value is %s, old storage value is %s",
                                val, disabledRwExported));
                        }
                    } catch (Exception e) {
                        Log.e(TAG, "error: failed to read flag value of disabledRwExported", e);
                    }
                }
                enabledRw =
                    properties.getBoolean(Flags.FLAG_ENABLED_RW, true);
                if (readFromNewStorage && reader != null) {
                    try {
                        val = reader.getBooleanFlagValue(8);
                        if (val == enabledRw) {
                            Log.i(TAG, "success: enabledRw value matches");
                        } else {
                            Log.i(TAG, String.format(
                                "error: enabledRw value mismatch, new storage value is %s, old storage value is %s",
                                val, enabledRw));
                        }
                    } catch (Exception e) {
                        Log.e(TAG, "error: failed to read flag value of enabledRw", e);
                    }
                }
            } 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 {
                boolean val;
                Properties properties = DeviceConfig.getProperties("other_namespace");
                disabledRwInOtherNamespace =
                    properties.getBoolean(Flags.FLAG_DISABLED_RW_IN_OTHER_NAMESPACE, false);
                if (readFromNewStorage && reader != null) {
                    try {
                        val = reader.getBooleanFlagValue(3);
                        if (val == disabledRwInOtherNamespace) {
                            Log.i(TAG, "success: disabledRwInOtherNamespace value matches");
                        } else {
                            Log.i(TAG, String.format(
                                "error: disabledRwInOtherNamespace value mismatch, new storage value is %s, old storage value is %s",
                                val, disabledRwInOtherNamespace));
                        }
                    } catch (Exception e) {
                        Log.e(TAG, "error: failed to read flag value of disabledRwInOtherNamespace", e);
                    }
                }
            } 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;
        }"# + 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/FeatureFlags.java", EXPECTED_FEATUREFLAGS_COMMON_CONTENT),
            (
                "com/android/aconfig/test/CustomFeatureFlags.java",
+0 −1
Original line number Diff line number Diff line
@@ -32,7 +32,6 @@ android_test {
        "androidx.test.runner",
        "junit",
    ],
    sdk_version: "test_current",
    test_config: "AndroidStorageJaveTest.xml",
    data: [
        "package.map",
+3 −0
Original line number Diff line number Diff line
@@ -171,6 +171,9 @@ java_library {
    srcs: [
        "srcs/android/aconfig/storage/StorageInternalReader.java",
    ],
    libs: [
        "unsupportedappusage",
    ],
    static_libs: [
        "aconfig_storage_file_java",
    ],
+6 −0
Original line number Diff line number Diff line
@@ -16,10 +16,13 @@

package android.aconfig.storage;

import android.compat.annotation.UnsupportedAppUsage;

import java.io.FileInputStream;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;

/** @hide */
public class StorageInternalReader {

    private static final String MAP_PATH = "/metadata/aconfig/maps/";
@@ -30,16 +33,19 @@ public class StorageInternalReader {

    private int mPackageBooleanStartOffset;

    @UnsupportedAppUsage
    public StorageInternalReader(String container, String packageName) {
        this(packageName, MAP_PATH + container + ".package.map", BOOT_PATH + container + ".val");
    }

    @UnsupportedAppUsage
    public StorageInternalReader(String packageName, String packageMapFile, String flagValueFile) {
        mPackageTable = PackageTable.fromBytes(mapStorageFile(packageMapFile));
        mFlagValueList = FlagValueList.fromBytes(mapStorageFile(flagValueFile));
        mPackageBooleanStartOffset = getPackageBooleanStartOffset(packageName);
    }

    @UnsupportedAppUsage
    public boolean getBooleanFlagValue(int index) {
        index += mPackageBooleanStartOffset;
        if (index >= mFlagValueList.size()) {
+2 −2

File changed.

Contains only whitespace changes.