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

Commit 2820b4b3 authored by Zhi Dou's avatar Zhi Dou Committed by Gerrit Code Review
Browse files

Merge "generated new exported code" into main

parents 1f07601d c70cff87
Loading
Loading
Loading
Loading
+189 −0
Original line number Diff line number Diff line
@@ -874,6 +874,195 @@ mod tests {
        assert!(file_set.is_empty());
    }

    #[test]
    fn test_generate_java_code_new_exported() {
        let parsed_flags = crate::test::parse_test_flags();
        let mode = CodegenMode::Exported;
        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,
            5801144784618221668,
            true,
        )
        .unwrap();

        let expect_flags_content = r#"
        package com.android.aconfig.test;
        /** @hide */
        public final class Flags {
            /** @hide */
            public static final String FLAG_DISABLED_RW_EXPORTED = "com.android.aconfig.test.disabled_rw_exported";
            /** @hide */
            public static final String FLAG_ENABLED_FIXED_RO_EXPORTED = "com.android.aconfig.test.enabled_fixed_ro_exported";
            /** @hide */
            public static final String FLAG_ENABLED_RO_EXPORTED = "com.android.aconfig.test.enabled_ro_exported";
            public static boolean disabledRwExported() {
                return FEATURE_FLAGS.disabledRwExported();
            }
            public static boolean enabledFixedRoExported() {
                return FEATURE_FLAGS.enabledFixedRoExported();
            }
            public static boolean enabledRoExported() {
                return FEATURE_FLAGS.enabledRoExported();
            }
            private static FeatureFlags FEATURE_FLAGS = new FeatureFlagsImpl();
        }
        "#;

        let expect_feature_flags_content = r#"
        package com.android.aconfig.test;
        /** @hide */
        public interface FeatureFlags {
            boolean disabledRwExported();
            boolean enabledFixedRoExported();
            boolean enabledRoExported();
        }
        "#;

        let expect_feature_flags_impl_content = r#"
        package com.android.aconfig.test;
        import android.os.flagging.AconfigPackage;
        import android.util.Log;
        /** @hide */
        public final class FeatureFlagsImpl implements FeatureFlags {
            private static final String TAG = "com.android.aconfig.test.FeatureFlagsImpl_exported";
            private static volatile boolean isCached = false;
            private static boolean disabledRwExported = false;
            private static boolean enabledFixedRoExported = false;
            private static boolean enabledRoExported = false;
            private void init() {
                try {
                    AconfigPackage reader = AconfigPackage.load("com.android.aconfig.test");
                    disabledRwExported = reader.getBooleanFlagValue("disabled_rw_exported", false);
                    enabledFixedRoExported = reader.getBooleanFlagValue("enabled_fixed_ro_exported", false);
                    enabledRoExported = reader.getBooleanFlagValue("enabled_ro_exported", false);
                } catch (Exception e) {
                    // pass
                    Log.e(TAG, e.toString());
                } catch (NoClassDefFoundError e) {
                    // for mainline module running on older devices.
                    // This should be replaces to version check, after the version bump.
                    Log.e(TAG, e.toString());
                }
                isCached = true;
            }
            @Override
            public boolean disabledRwExported() {
                if (!isCached) {
                    init();
                }
                return disabledRwExported;
            }
            @Override
            public boolean enabledFixedRoExported() {
                if (!isCached) {
                    init();
                }
                return enabledFixedRoExported;
            }
            @Override
            public boolean enabledRoExported() {
                if (!isCached) {
                    init();
                }
                return enabledRoExported;
            }
        }"#;

        let expect_custom_feature_flags_content = r#"
        package com.android.aconfig.test;

        import java.util.Arrays;
        import java.util.HashSet;
        import java.util.List;
        import java.util.Set;
        import java.util.function.BiPredicate;
        import java.util.function.Predicate;

        /** @hide */
        public class CustomFeatureFlags implements FeatureFlags {

            private BiPredicate<String, Predicate<FeatureFlags>> mGetValueImpl;

            public CustomFeatureFlags(BiPredicate<String, Predicate<FeatureFlags>> getValueImpl) {
                mGetValueImpl = getValueImpl;
            }

            @Override
            public boolean disabledRwExported() {
                return getValue(Flags.FLAG_DISABLED_RW_EXPORTED,
                    FeatureFlags::disabledRwExported);
            }
            @Override
            public boolean enabledFixedRoExported() {
                return getValue(Flags.FLAG_ENABLED_FIXED_RO_EXPORTED,
                    FeatureFlags::enabledFixedRoExported);
            }
            @Override
            public boolean enabledRoExported() {
                return getValue(Flags.FLAG_ENABLED_RO_EXPORTED,
                    FeatureFlags::enabledRoExported);
            }

            protected boolean getValue(String flagName, Predicate<FeatureFlags> getter) {
                return mGetValueImpl.test(flagName, getter);
            }

            public List<String> getFlagNames() {
                return Arrays.asList(
                    Flags.FLAG_DISABLED_RW_EXPORTED,
                    Flags.FLAG_ENABLED_FIXED_RO_EXPORTED,
                    Flags.FLAG_ENABLED_RO_EXPORTED
                );
            }

            private Set<String> mReadOnlyFlagsSet = new HashSet<>(
                Arrays.asList(
                    ""
                )
            );
        }
    "#;

        let mut file_set = HashMap::from([
            ("com/android/aconfig/test/Flags.java", expect_flags_content),
            ("com/android/aconfig/test/FeatureFlags.java", expect_feature_flags_content),
            ("com/android/aconfig/test/FeatureFlagsImpl.java", expect_feature_flags_impl_content),
            (
                "com/android/aconfig/test/CustomFeatureFlags.java",
                expect_custom_feature_flags_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());
    }

    #[test]
    fn test_generate_java_code_test() {
        let parsed_flags = crate::test::parse_test_flags();
+40 −0
Original line number Diff line number Diff line
@@ -65,6 +65,45 @@ public final class FeatureFlagsImpl implements FeatureFlags \{
{{ endfor }}
}
{{ -else- }}{#- device config for exproted mode #}
{{ -if new_exported }}
import android.os.flagging.AconfigPackage;
import android.util.Log;
/** @hide */
public final class FeatureFlagsImpl implements FeatureFlags \{
    private static final String TAG = "{package_name}.FeatureFlagsImpl_exported";
    private static volatile boolean isCached = false;
{{ for flag in flag_elements }}
    private static boolean {flag.method_name} = {flag.default_value};
{{ -endfor }}
    private void init() \{
        try \{
            AconfigPackage reader = AconfigPackage.load("{package_name}");
            {{ -for namespace_with_flags in namespace_flags }}
            {{ -for flag in namespace_with_flags.flags }}
            {flag.method_name} = reader.getBooleanFlagValue("{flag.flag_name}", {flag.default_value});
            {{ -endfor }}
            {{ -endfor }}
        } catch (Exception e) \{
            // pass
            Log.e(TAG, e.toString());
        } catch (NoClassDefFoundError e) \{
            // for mainline module running on older devices.
            // This should be replaces to version check, after the version bump.
            Log.e(TAG, e.toString());
        }
        isCached = true;
    }
{{ -for flag in flag_elements }}
    @Override
    public boolean {flag.method_name}() \{
        if (!isCached) \{
            init();
        }
        return {flag.method_name};
    }
{{ endfor }}
}
{{ else }}
import android.os.Binder;
import android.provider.DeviceConfig;
import android.provider.DeviceConfig.Properties;
@@ -116,6 +155,7 @@ public final class FeatureFlagsImpl implements FeatureFlags \{
    }
{{ endfor }}
}
{{ -endif- }} {#- end new_exported mode #}
{{ -endif- }} {#- end exported mode #}
{{ else }} {#- else for allow_instrumentation is not enabled #}
{{ if not library_exported- }}