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

Commit aeb96092 authored by Ted Bauer's avatar Ted Bauer
Browse files

Add filter by container to aflags

Test: m -j120 && acloud create --local-image && adb shell aflags list --c system
Test: cargo t
Bug: 340840507
Change-Id: I5db7f204673accdbd3c4ad62e88b213028a8d5ab
parent 4a2c1b5c
Loading
Loading
Loading
Loading
+1 −2
Original line number Original line Diff line number Diff line
@@ -27,8 +27,7 @@ impl FlagSource for AconfigStorageSource {
            let container =
            let container =
                file_info.container.ok_or(anyhow!("storage file is missing container"))?;
                file_info.container.ok_or(anyhow!("storage file is missing container"))?;


            for listed_flag in
            for listed_flag in aconfig_storage_file::list_flags(&package_map, &flag_map, &flag_val)?
                aconfig_storage_file::list_flags(&package_map, &flag_map, &flag_val)?
            {
            {
                result.push(Flag {
                result.push(Flag {
                    name: listed_flag.flag_name,
                    name: listed_flag.flag_name,
+135 −16
Original line number Original line Diff line number Diff line
@@ -35,10 +35,14 @@ enum FlagPermission {


impl std::fmt::Display for FlagPermission {
impl std::fmt::Display for FlagPermission {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "{}", match &self {
        write!(
            f,
            "{}",
            match &self {
                Self::ReadOnly => "read-only",
                Self::ReadOnly => "read-only",
                Self::ReadWrite => "read-write",
                Self::ReadWrite => "read-write",
        })
            }
        )
    }
    }
}
}


@@ -50,10 +54,14 @@ enum ValuePickedFrom {


impl std::fmt::Display for ValuePickedFrom {
impl std::fmt::Display for ValuePickedFrom {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "{}", match &self {
        write!(
            f,
            "{}",
            match &self {
                Self::Default => "default",
                Self::Default => "default",
                Self::Server => "server",
                Self::Server => "server",
        })
            }
        )
    }
    }
}
}


@@ -77,10 +85,14 @@ impl TryFrom<&str> for FlagValue {


impl std::fmt::Display for FlagValue {
impl std::fmt::Display for FlagValue {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "{}", match &self {
        write!(
            f,
            "{}",
            match &self {
                Self::Enabled => "enabled",
                Self::Enabled => "enabled",
                Self::Disabled => "disabled",
                Self::Disabled => "disabled",
        })
            }
        )
    }
    }
}
}


@@ -153,6 +165,10 @@ enum Command {
        /// Read from the new flag storage.
        /// Read from the new flag storage.
        #[clap(long)]
        #[clap(long)]
        use_new_storage: bool,
        use_new_storage: bool,

        /// Optionally filter by container name.
        #[clap(short = 'c', long = "container")]
        container: Option<String>,
    },
    },


    /// Enable an aconfig flag on this device, on the next boot.
    /// Enable an aconfig flag on this device, on the next boot.
@@ -176,6 +192,23 @@ struct PaddingInfo {
    longest_permission_col: usize,
    longest_permission_col: usize,
}
}


struct Filter {
    container: Option<String>,
}

impl Filter {
    fn apply(&self, flags: &[Flag]) -> Vec<Flag> {
        flags
            .iter()
            .filter(|flag| match &self.container {
                Some(c) => flag.container == *c,
                None => true,
            })
            .cloned()
            .collect()
    }
}

fn format_flag_row(flag: &Flag, info: &PaddingInfo) -> String {
fn format_flag_row(flag: &Flag, info: &PaddingInfo) -> String {
    let full_name = flag.qualified_name();
    let full_name = flag.qualified_name();
    let p0 = info.longest_flag_col + 1;
    let p0 = info.longest_flag_col + 1;
@@ -215,11 +248,12 @@ fn set_flag(qualified_name: &str, value: &str) -> Result<()> {
    Ok(())
    Ok(())
}
}


fn list(source_type: FlagSourceType) -> Result<String> {
fn list(source_type: FlagSourceType, container: Option<String>) -> Result<String> {
    let flags = match source_type {
    let flags_unfiltered = match source_type {
        FlagSourceType::DeviceConfig => DeviceConfigSource::list_flags()?,
        FlagSourceType::DeviceConfig => DeviceConfigSource::list_flags()?,
        FlagSourceType::AconfigStorage => AconfigStorageSource::list_flags()?,
        FlagSourceType::AconfigStorage => AconfigStorageSource::list_flags()?,
    };
    };
    let flags = (Filter { container }).apply(&flags_unfiltered);
    let padding_info = PaddingInfo {
    let padding_info = PaddingInfo {
        longest_flag_col: flags.iter().map(|f| f.qualified_name().len()).max().unwrap_or(0),
        longest_flag_col: flags.iter().map(|f| f.qualified_name().len()).max().unwrap_or(0),
        longest_val_col: flags.iter().map(|f| f.value.to_string().len()).max().unwrap_or(0),
        longest_val_col: flags.iter().map(|f| f.value.to_string().len()).max().unwrap_or(0),
@@ -251,8 +285,12 @@ fn list(source_type: FlagSourceType) -> Result<String> {
fn main() {
fn main() {
    let cli = Cli::parse();
    let cli = Cli::parse();
    let output = match cli.command {
    let output = match cli.command {
        Command::List { use_new_storage: true } => list(FlagSourceType::AconfigStorage).map(Some),
        Command::List { use_new_storage: true, container } => {
        Command::List { use_new_storage: false } => list(FlagSourceType::DeviceConfig).map(Some),
            list(FlagSourceType::AconfigStorage, container).map(Some)
        }
        Command::List { use_new_storage: false, container } => {
            list(FlagSourceType::DeviceConfig, container).map(Some)
        }
        Command::Enable { qualified_name } => set_flag(&qualified_name, "true").map(|_| None),
        Command::Enable { qualified_name } => set_flag(&qualified_name, "true").map(|_| None),
        Command::Disable { qualified_name } => set_flag(&qualified_name, "false").map(|_| None),
        Command::Disable { qualified_name } => set_flag(&qualified_name, "false").map(|_| None),
    };
    };
@@ -262,3 +300,84 @@ fn main() {
        Err(message) => println!("Error: {message}"),
        Err(message) => println!("Error: {message}"),
    }
    }
}
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_filter_container() {
        let flags = vec![
            Flag {
                namespace: "namespace".to_string(),
                name: "test1".to_string(),
                package: "package".to_string(),
                value: FlagValue::Disabled,
                staged_value: None,
                permission: FlagPermission::ReadWrite,
                value_picked_from: ValuePickedFrom::Default,
                container: "system".to_string(),
            },
            Flag {
                namespace: "namespace".to_string(),
                name: "test2".to_string(),
                package: "package".to_string(),
                value: FlagValue::Disabled,
                staged_value: None,
                permission: FlagPermission::ReadWrite,
                value_picked_from: ValuePickedFrom::Default,
                container: "not_system".to_string(),
            },
            Flag {
                namespace: "namespace".to_string(),
                name: "test3".to_string(),
                package: "package".to_string(),
                value: FlagValue::Disabled,
                staged_value: None,
                permission: FlagPermission::ReadWrite,
                value_picked_from: ValuePickedFrom::Default,
                container: "system".to_string(),
            },
        ];

        assert_eq!((Filter { container: Some("system".to_string()) }).apply(&flags).len(), 2);
    }

    #[test]
    fn test_filter_no_container() {
        let flags = vec![
            Flag {
                namespace: "namespace".to_string(),
                name: "test1".to_string(),
                package: "package".to_string(),
                value: FlagValue::Disabled,
                staged_value: None,
                permission: FlagPermission::ReadWrite,
                value_picked_from: ValuePickedFrom::Default,
                container: "system".to_string(),
            },
            Flag {
                namespace: "namespace".to_string(),
                name: "test2".to_string(),
                package: "package".to_string(),
                value: FlagValue::Disabled,
                staged_value: None,
                permission: FlagPermission::ReadWrite,
                value_picked_from: ValuePickedFrom::Default,
                container: "not_system".to_string(),
            },
            Flag {
                namespace: "namespace".to_string(),
                name: "test3".to_string(),
                package: "package".to_string(),
                value: FlagValue::Disabled,
                staged_value: None,
                permission: FlagPermission::ReadWrite,
                value_picked_from: ValuePickedFrom::Default,
                container: "system".to_string(),
            },
        ];

        assert_eq!((Filter { container: None }).apply(&flags).len(), 3);
    }
}