Merge "Prevent VABC from being disabled on release-key builds" into main
diff --git a/core/soong_config.mk b/core/soong_config.mk
index e3eb780..52bcd9a 100644
--- a/core/soong_config.mk
+++ b/core/soong_config.mk
@@ -40,7 +40,9 @@
$(call add_json_str, Platform_base_os, $(PLATFORM_BASE_OS))
$(call add_json_str, Platform_version_last_stable, $(PLATFORM_VERSION_LAST_STABLE))
$(call add_json_str, Platform_version_known_codenames, $(PLATFORM_VERSION_KNOWN_CODENAMES))
+
$(call add_json_bool, Release_aidl_use_unfrozen, $(RELEASE_AIDL_USE_UNFROZEN))
+$(call add_json_bool, Release_expose_flagged_api, $(RELEASE_EXPOSE_FLAGGED_API))
$(call add_json_str, Platform_min_supported_target_sdk_version, $(PLATFORM_MIN_SUPPORTED_TARGET_SDK_VERSION))
diff --git a/target/product/base_system.mk b/target/product/base_system.mk
index f8dbafd..29e4ecd 100644
--- a/target/product/base_system.mk
+++ b/target/product/base_system.mk
@@ -235,6 +235,7 @@
pm \
pppd \
preinstalled-packages-platform.xml \
+ printflags \
privapp-permissions-platform.xml \
prng_seeder \
racoon \
diff --git a/tools/aconfig/printflags/Android.bp b/tools/aconfig/printflags/Android.bp
index 5d73d96..da18cdc 100644
--- a/tools/aconfig/printflags/Android.bp
+++ b/tools/aconfig/printflags/Android.bp
@@ -2,8 +2,8 @@
default_applicable_licenses: ["Android-Apache-2.0"],
}
-rust_binary {
- name: "printflags",
+rust_defaults {
+ name: "printflags.defaults",
edition: "2021",
clippy_lints: "android",
lints: "android",
@@ -12,5 +12,16 @@
"libaconfig_protos",
"libanyhow",
"libprotobuf",
+ "libregex",
],
}
+
+rust_binary {
+ name: "printflags",
+ defaults: ["printflags.defaults"],
+}
+
+rust_test_host {
+ name: "printflags.test",
+ defaults: ["printflags.defaults"],
+}
diff --git a/tools/aconfig/printflags/src/main.rs b/tools/aconfig/printflags/src/main.rs
index a9f7c03..88fdea9 100644
--- a/tools/aconfig/printflags/src/main.rs
+++ b/tools/aconfig/printflags/src/main.rs
@@ -16,12 +16,43 @@
//! `printflags` is a device binary to print feature flags.
+use aconfig_protos::aconfig::Flag_state as State;
use aconfig_protos::aconfig::Parsed_flags as ProtoParsedFlags;
-use anyhow::Result;
+use anyhow::{bail, Result};
+use regex::Regex;
use std::collections::HashMap;
-use std::fs;
+use std::process::Command;
+use std::{fs, str};
+
+fn parse_device_config(raw: &str) -> HashMap<String, String> {
+ let mut flags = HashMap::new();
+ let regex = Regex::new(r"(?m)^([[[:alnum:]]_]+/[[[:alnum:]]_\.]+)=(true|false)$").unwrap();
+ for capture in regex.captures_iter(raw) {
+ let key = capture.get(1).unwrap().as_str().to_string();
+ let value = match capture.get(2).unwrap().as_str() {
+ "true" => format!("{:?} (device_config)", State::ENABLED),
+ "false" => format!("{:?} (device_config)", State::DISABLED),
+ _ => panic!(),
+ };
+ flags.insert(key, value);
+ }
+ flags
+}
fn main() -> Result<()> {
+ // read device_config
+ let output = Command::new("/system/bin/device_config").arg("list").output()?;
+ if !output.status.success() {
+ let reason = match output.status.code() {
+ Some(code) => format!("exit code {}", code),
+ None => "terminated by signal".to_string(),
+ };
+ bail!("failed to execute device_config: {}", reason);
+ }
+ let dc_stdout = str::from_utf8(&output.stdout)?;
+ let device_config_flags = parse_device_config(dc_stdout);
+
+ // read aconfig_flags.pb files
let mut flags: HashMap<String, Vec<String>> = HashMap::new();
for partition in ["system", "system_ext", "product", "vendor"] {
let path = format!("/{}/etc/aconfig_flags.pb", partition);
@@ -31,15 +62,49 @@
};
let parsed_flags: ProtoParsedFlags = protobuf::Message::parse_from_bytes(&bytes)?;
for flag in parsed_flags.parsed_flag {
- let key = format!("{}.{}", flag.package(), flag.name());
+ let key = format!("{}/{}.{}", flag.namespace(), flag.package(), flag.name());
let value = format!("{:?} + {:?} ({})", flag.permission(), flag.state(), partition);
flags.entry(key).or_default().push(value);
}
}
- for (key, value) in flags {
- // TODO: if the flag is READ_WRITE (for any partition), call "device_config get" to obtain
- // the flag's current state, and append value to the output
- println!("{}: {}", key, value.join(", "));
+
+ // print flags
+ for (key, mut value) in flags {
+ let (_, package_and_name) = key.split_once('/').unwrap();
+ if let Some(dc_value) = device_config_flags.get(&key) {
+ value.push(dc_value.to_string());
+ }
+ println!("{}: {}", package_and_name, value.join(", "));
}
+
Ok(())
}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn test_foo() {
+ let input = r#"
+namespace_one/com.foo.bar.flag_one=true
+namespace_one/com.foo.bar.flag_two=false
+random_noise;
+namespace_two/android.flag_one=true
+namespace_two/android.flag_two=nonsense
+"#;
+ let expected = HashMap::from([
+ (
+ "namespace_one/com.foo.bar.flag_one".to_string(),
+ "ENABLED (device_config)".to_string(),
+ ),
+ (
+ "namespace_one/com.foo.bar.flag_two".to_string(),
+ "DISABLED (device_config)".to_string(),
+ ),
+ ("namespace_two/android.flag_one".to_string(), "ENABLED (device_config)".to_string()),
+ ]);
+ let actual = parse_device_config(input);
+ assert_eq!(expected, actual);
+ }
+}