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

Commit 3ff3d49c authored by Marybeth Fair's avatar Marybeth Fair Committed by Gerrit Code Review
Browse files

Merge "aconfig: Add API level check to exported mode." into main

parents 83f593a1 2f42c766
Loading
Loading
Loading
Loading
+72 −37
Original line number Diff line number Diff line
@@ -26,25 +26,34 @@ use crate::commands::{should_include_flag, OutputFile};
use aconfig_protos::{ProtoFlagPermission, ProtoFlagState, ProtoParsedFlag};
use std::collections::HashMap;

// Arguments to configure codegen for generate_java_code.
pub struct JavaCodegenConfig {
    pub codegen_mode: CodegenMode,
    pub flag_ids: HashMap<String, u16>,
    pub allow_instrumentation: bool,
    pub package_fingerprint: u64,
    pub new_exported: bool,
    pub check_api_level: bool,
}

pub fn generate_java_code<I>(
    package: &str,
    parsed_flags_iter: I,
    codegen_mode: CodegenMode,
    flag_ids: HashMap<String, u16>,
    allow_instrumentation: bool,
    package_fingerprint: u64,
    new_exported: bool,
    config: JavaCodegenConfig,
) -> Result<Vec<OutputFile>>
where
    I: Iterator<Item = ProtoParsedFlag>,
{
    let flag_elements: Vec<FlagElement> =
        parsed_flags_iter.map(|pf| create_flag_element(package, &pf, flag_ids.clone())).collect();
    let flag_elements: Vec<FlagElement> = parsed_flags_iter
        .map(|pf| {
            create_flag_element(package, &pf, config.flag_ids.clone(), config.check_api_level)
        })
        .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_test_mode = codegen_mode == CodegenMode::Test;
    let library_exported = codegen_mode == CodegenMode::Exported;
    let is_test_mode = config.codegen_mode == CodegenMode::Test;
    let library_exported = config.codegen_mode == CodegenMode::Exported;
    let runtime_lookup_required =
        flag_elements.iter().any(|elem| elem.is_read_write) || library_exported;
    let container = (flag_elements.first().expect("zero template flags").container).to_string();
@@ -57,11 +66,11 @@ where
        properties_set,
        package_name: package.to_string(),
        library_exported,
        allow_instrumentation,
        allow_instrumentation: config.allow_instrumentation,
        container,
        is_platform_container,
        package_fingerprint: format!("0x{:X}L", package_fingerprint),
        new_exported,
        package_fingerprint: format!("0x{:X}L", config.package_fingerprint),
        new_exported: config.new_exported,
    };
    let mut template = TinyTemplate::new();
    template.add_template("Flags.java", include_str!("../../templates/Flags.java.template"))?;
@@ -152,12 +161,15 @@ struct FlagElement {
    pub is_read_write: bool,
    pub method_name: String,
    pub properties: String,
    pub finalized_sdk_present: bool,
    pub finalized_sdk_value: i32,
}

fn create_flag_element(
    package: &str,
    pf: &ProtoParsedFlag,
    flag_offsets: HashMap<String, u16>,
    check_api_level: bool,
) -> FlagElement {
    let device_config_flag = codegen::create_device_config_ident(package, pf.name())
        .expect("values checked at flag parse time");
@@ -190,6 +202,8 @@ fn create_flag_element(
        is_read_write: pf.permission() == ProtoFlagPermission::READ_WRITE,
        method_name: format_java_method_name(pf.name()),
        properties: format_property_name(pf.namespace()),
        finalized_sdk_present: check_api_level,
        finalized_sdk_value: i32::MAX, // TODO: b/378936061 - Read value from artifact.
    }
}

@@ -523,14 +537,18 @@ mod tests {
            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 config = JavaCodegenConfig {
            codegen_mode: mode,
            flag_ids,
            allow_instrumentation: true,
            package_fingerprint: 5801144784618221668,
            new_exported: false,
            check_api_level: false,
        };
        let generated_files = generate_java_code(
            crate::test::TEST_PACKAGE,
            modified_parsed_flags.into_iter(),
            mode,
            flag_ids,
            true,
            5801144784618221668,
            false,
            config,
        )
        .unwrap();
        let expect_flags_content = EXPECTED_FLAG_COMMON_CONTENT.to_string()
@@ -679,14 +697,18 @@ mod tests {
            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 config = JavaCodegenConfig {
            codegen_mode: mode,
            flag_ids,
            allow_instrumentation: true,
            package_fingerprint: 5801144784618221668,
            new_exported: false,
            check_api_level: false,
        };
        let generated_files = generate_java_code(
            crate::test::TEST_PACKAGE,
            modified_parsed_flags.into_iter(),
            mode,
            flag_ids,
            true,
            5801144784618221668,
            false,
            config,
        )
        .unwrap();

@@ -879,14 +901,18 @@ mod tests {
            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 config = JavaCodegenConfig {
            codegen_mode: mode,
            flag_ids,
            allow_instrumentation: true,
            package_fingerprint: 5801144784618221668,
            new_exported: true,
            check_api_level: false,
        };
        let generated_files = generate_java_code(
            crate::test::TEST_PACKAGE,
            modified_parsed_flags.into_iter(),
            mode,
            flag_ids,
            true,
            5801144784618221668,
            true,
            config,
        )
        .unwrap();

@@ -925,6 +951,7 @@ mod tests {

        let expect_feature_flags_impl_content = r#"
        package com.android.aconfig.test;
        import android.os.Build;
        import android.os.flagging.AconfigPackage;
        import android.util.Log;
        /** @hide */
@@ -1068,14 +1095,18 @@ mod tests {
            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 config = JavaCodegenConfig {
            codegen_mode: mode,
            flag_ids,
            allow_instrumentation: true,
            package_fingerprint: 5801144784618221668,
            new_exported: false,
            check_api_level: false,
        };
        let generated_files = generate_java_code(
            crate::test::TEST_PACKAGE,
            modified_parsed_flags.into_iter(),
            mode,
            flag_ids,
            true,
            5801144784618221668,
            false,
            config,
        )
        .unwrap();

@@ -1191,14 +1222,18 @@ mod tests {
            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 config = JavaCodegenConfig {
            codegen_mode: mode,
            flag_ids,
            allow_instrumentation: true,
            package_fingerprint: 5801144784618221668,
            new_exported: false,
            check_api_level: false,
        };
        let generated_files = generate_java_code(
            crate::test::TEST_PACKAGE,
            modified_parsed_flags.into_iter(),
            mode,
            flag_ids,
            true,
            5801144784618221668,
            false,
            config,
        )
        .unwrap();
        let expect_featureflags_content = r#"
+6 −5
Original line number Diff line number Diff line
@@ -23,7 +23,7 @@ use std::io::Read;
use std::path::PathBuf;

use crate::codegen::cpp::generate_cpp_code;
use crate::codegen::java::generate_java_code;
use crate::codegen::java::{generate_java_code, JavaCodegenConfig};
use crate::codegen::rust::generate_rust_code;
use crate::codegen::CodegenMode;
use crate::dump::{DumpFormat, DumpPredicate};
@@ -219,6 +219,7 @@ pub fn create_java_lib(
    codegen_mode: CodegenMode,
    allow_instrumentation: bool,
    new_exported: bool,
    check_api_level: bool,
) -> Result<Vec<OutputFile>> {
    let parsed_flags = input.try_parse_flags()?;
    let modified_parsed_flags =
@@ -230,15 +231,15 @@ pub fn create_java_lib(
    let mut flag_names = extract_flag_names(parsed_flags)?;
    let package_fingerprint = compute_flags_fingerprint(&mut flag_names);
    let flag_ids = assign_flag_ids(&package, modified_parsed_flags.iter())?;
    generate_java_code(
        &package,
        modified_parsed_flags.into_iter(),
    let config = JavaCodegenConfig {
        codegen_mode,
        flag_ids,
        allow_instrumentation,
        package_fingerprint,
        new_exported,
    )
        check_api_level,
    };
    generate_java_code(&package, modified_parsed_flags.into_iter(), config)
}

pub fn create_cpp_lib(
+19 −3
Original line number Diff line number Diff line
@@ -91,6 +91,16 @@ fn cli() -> Command {
                        .long("new-exported")
                        .value_parser(clap::value_parser!(bool))
                        .default_value("false"),
                )
                // Allows build flag toggling of checking API level in exported
                // flag lib for finalized API flags.
                // TODO: b/378936061 - Remove once build flag for API level
                // check is fully enabled.
                .arg(
                    Arg::new("check-api-level")
                        .long("check-api-level")
                        .value_parser(clap::value_parser!(bool))
                        .default_value("false"),
                ),
        )
        .subcommand(
@@ -274,8 +284,14 @@ fn main() -> Result<()> {
            let allow_instrumentation =
                get_required_arg::<bool>(sub_matches, "allow-instrumentation")?;
            let new_exported = get_required_arg::<bool>(sub_matches, "new-exported")?;
            let generated_files =
                commands::create_java_lib(cache, *mode, *allow_instrumentation, *new_exported)
            let check_api_level = get_required_arg::<bool>(sub_matches, "check-api-level")?;
            let generated_files = commands::create_java_lib(
                cache,
                *mode,
                *allow_instrumentation,
                *new_exported,
                *check_api_level,
            )
            .context("failed to create java lib")?;
            let dir = PathBuf::from(get_required_arg::<String>(sub_matches, "out")?);
            generated_files
+5 −0
Original line number Diff line number Diff line
@@ -66,6 +66,7 @@ public final class FeatureFlagsImpl implements FeatureFlags \{
}
{{ -else- }}{#- device config for exproted mode #}
{{ -if new_exported }}
import android.os.Build;
import android.os.flagging.AconfigPackage;
import android.util.Log;
/** @hide */
@@ -80,7 +81,11 @@ public final class FeatureFlagsImpl implements FeatureFlags \{
            AconfigPackage reader = AconfigPackage.load("{package_name}");
            {{ -for namespace_with_flags in namespace_flags }}
            {{ -for flag in namespace_with_flags.flags }}
            {{ -if flag.finalized_sdk_present }}
            {flag.method_name} = Build.VERSION.SDK_INT >= {flag.finalized_sdk_value} ? true : reader.getBooleanFlagValue("{flag.flag_name}", {flag.default_value});
            {{ - else }}
            {flag.method_name} = reader.getBooleanFlagValue("{flag.flag_name}", {flag.default_value});
            {{ -endif}}
            {{ -endfor }}
            {{ -endfor }}
        } catch (Exception e) \{