From c31a6ff6534dfa558f1dda484fffd192d55eb17c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A5rten=20Kongstad?= Date: Fri, 2 Jun 2023 11:54:36 +0200 Subject: [PATCH] aconfig: add create-device-config-sysprops command Add a new "create-device-config-sysprops" command that works like "create-device-config-defaults" but for system properties. DeviceConfig is a Java service, and will mirror (some of) its values by setting system properties in the persist.device_config namespace. Native code will access DeviceConfig (actually, the system properties) via the server_configurable_flags library. The new command writes a file that can be appended to /system/build.prop to pre-populate persist.device_config before DeviceConfig has started. Like create-device-config-defaults, the new command skips READ_ONLY flags. Bug: 285468565 Test: atest aconfig.test Change-Id: I311c7c5e0b03dc897b09204137d43cc182324717 --- tools/aconfig/src/commands.rs | 26 ++++++++++++++++++++++++++ tools/aconfig/src/main.rs | 16 ++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/tools/aconfig/src/commands.rs b/tools/aconfig/src/commands.rs index d5e47daa1b..3ae72c67fa 100644 --- a/tools/aconfig/src/commands.rs +++ b/tools/aconfig/src/commands.rs @@ -123,6 +123,24 @@ pub fn create_device_config_defaults(caches: Vec) -> Result> { Ok(output) } +pub fn create_device_config_sysprops(caches: Vec) -> Result> { + let mut output = Vec::new(); + for item in sort_and_iter_items(caches).filter(|item| item.permission == Permission::ReadWrite) + { + let line = format!( + "persist.device_config.{}.{}={}\n", + item.namespace, + item.name, + match item.state { + FlagState::Enabled => "true", + FlagState::Disabled => "false", + } + ); + output.extend_from_slice(line.as_bytes()); + } + Ok(output) +} + #[derive(Copy, Clone, Debug, PartialEq, Eq, ValueEnum)] pub enum DumpFormat { Text, @@ -234,6 +252,14 @@ mod tests { assert_eq!("test/disabled_rw:disabled\ntest/enabled_rw:enabled\n", text); } + #[test] + fn test_create_device_config_sysprops() { + let caches = vec![crate::test::create_cache()]; + let bytes = create_device_config_sysprops(caches).unwrap(); + let text = std::str::from_utf8(&bytes).unwrap(); + assert_eq!("persist.device_config.test.disabled_rw=false\npersist.device_config.test.enabled_rw=true\n", text); + } + #[test] fn test_dump_text_format() { let caches = vec![create_test_cache_ns1()]; diff --git a/tools/aconfig/src/main.rs b/tools/aconfig/src/main.rs index f632ce7efc..dab01918f0 100644 --- a/tools/aconfig/src/main.rs +++ b/tools/aconfig/src/main.rs @@ -69,6 +69,11 @@ fn cli() -> Command { .arg(Arg::new("cache").long("cache").action(ArgAction::Append).required(true)) .arg(Arg::new("out").long("out").default_value("-")), ) + .subcommand( + Command::new("create-device-config-sysprops") + .arg(Arg::new("cache").long("cache").action(ArgAction::Append).required(true)) + .arg(Arg::new("out").long("out").default_value("-")), + ) .subcommand( Command::new("dump") .arg(Arg::new("cache").long("cache").action(ArgAction::Append).required(true)) @@ -172,6 +177,17 @@ fn main() -> Result<()> { let path = get_required_arg::(sub_matches, "out")?; write_output_to_file_or_stdout(path, &output)?; } + Some(("create-device-config-sysprops", sub_matches)) => { + let mut caches = Vec::new(); + for path in sub_matches.get_many::("cache").unwrap_or_default() { + let file = fs::File::open(path)?; + let cache = Cache::read_from_reader(file)?; + caches.push(cache); + } + let output = commands::create_device_config_sysprops(caches)?; + let path = get_required_arg::(sub_matches, "out")?; + write_output_to_file_or_stdout(path, &output)?; + } Some(("dump", sub_matches)) => { let mut caches = Vec::new(); for path in sub_matches.get_many::("cache").unwrap_or_default() {