Specify system server compiler filter if configured
Not all devices have dalvik.vm.systemservercompilerfilter defined, but
when they do, we need to respect the vendor's configuration.
ComposHostTestCases now tests both speed and speed-profile explicitly,
rather than using the default value (which should be tested later in the
e2e test).
Add services.jar.prof to the temporary allowlist so that it can be
accessed from the VM's ANDROID_ROOT.
Bug: 208269838
Test: atest ComposHostTestCases
Test: setprop dalvik.vm.systemservercompilerfilter speed-profile
composd_cmd async-odrefresh
# Observed the odrefresh flag in VM's log
Change-Id: I1348a62834b9a65dde3e74a648394916473cda16
diff --git a/authfs/src/main.rs b/authfs/src/main.rs
index 3bd96f4..18b7b51 100644
--- a/authfs/src/main.rs
+++ b/authfs/src/main.rs
@@ -269,6 +269,7 @@
Path::new("/system/framework/framework.jar"),
Path::new("/system/framework/ims-common.jar"),
Path::new("/system/framework/services.jar"),
+ Path::new("/system/framework/services.jar.prof"),
Path::new("/system/framework/telephony-common.jar"),
Path::new("/system/framework/voip-common.jar"),
Path::new("/system/etc/boot-image.prof"),
diff --git a/compos/aidl/com/android/compos/ICompOsService.aidl b/compos/aidl/com/android/compos/ICompOsService.aidl
index 1a28a18..e3e0317 100644
--- a/compos/aidl/com/android/compos/ICompOsService.aidl
+++ b/compos/aidl/com/android/compos/ICompOsService.aidl
@@ -45,10 +45,11 @@
* @param targetDirName The sub-directory of the output directory to which artifacts are to be
* written (e.g. dalvik-cache)
* @param zygoteArch The zygote architecture (ro.zygote)
+ * @param systemServerCompilerFilter The compiler filter used to compile system server
* @return odrefresh exit code
*/
byte odrefresh(int systemDirFd, int outputDirFd, int stagingDirFd, String targetDirName,
- String zygoteArch);
+ String zygoteArch, String systemServerCompilerFilter);
/**
* Run dex2oat command with provided args, in a context that may be specified in FdAnnotation,
diff --git a/compos/composd/src/odrefresh_task.rs b/compos/composd/src/odrefresh_task.rs
index 56b697e..330f0ab 100644
--- a/compos/composd/src/odrefresh_task.rs
+++ b/compos/composd/src/odrefresh_task.rs
@@ -131,12 +131,15 @@
let fd_server_raii = fd_server_config.into_fd_server()?;
let zygote_arch = system_properties::read("ro.zygote")?;
+ let system_server_compiler_filter =
+ system_properties::read("dalvik.vm.systemservercompilerfilter").unwrap_or_default();
let exit_code = service.odrefresh(
system_dir.as_raw_fd(),
output_dir.as_raw_fd(),
staging_dir.as_raw_fd(),
target_dir_name,
&zygote_arch,
+ &system_server_compiler_filter,
)?;
drop(fd_server_raii);
diff --git a/compos/src/compilation.rs b/compos/src/compilation.rs
index af7a9b4..50d79c1 100644
--- a/compos/src/compilation.rs
+++ b/compos/src/compilation.rs
@@ -70,6 +70,7 @@
staging_dir_fd: i32,
target_dir_name: &'a str,
zygote_arch: &'a str,
+ system_server_compiler_filter: &'a str,
}
impl<'a> OdrefreshContext<'a> {
@@ -79,11 +80,12 @@
staging_dir_fd: i32,
target_dir_name: &'a str,
zygote_arch: &'a str,
+ system_server_compiler_filter: &'a str,
) -> Result<Self> {
if system_dir_fd < 0 || output_dir_fd < 0 || staging_dir_fd < 0 {
bail!("The remote FDs are expected to be non-negative");
}
- if zygote_arch != "zygote64" && zygote_arch != "zygote64_32" {
+ if !matches!(zygote_arch, "zygote64" | "zygote64_32") {
bail!("Invalid zygote arch");
}
// Disallow any sort of path traversal
@@ -91,7 +93,20 @@
bail!("Invalid target directory {}", target_dir_name);
}
- Ok(Self { system_dir_fd, output_dir_fd, staging_dir_fd, target_dir_name, zygote_arch })
+ // We're not validating/allowlisting the compiler filter, and just assume the compiler will
+ // reject an invalid string. We need to accept "verify" filter anyway, and potential
+ // performance degration by the attacker is not currently in scope. This also allows ART to
+ // specify new compiler filter and configure through system property without change to
+ // CompOS.
+
+ Ok(Self {
+ system_dir_fd,
+ output_dir_fd,
+ staging_dir_fd,
+ target_dir_name,
+ zygote_arch,
+ system_server_compiler_filter,
+ })
}
}
@@ -134,14 +149,22 @@
set_classpaths(&android_root)?;
- let args = vec![
+ let mut args = vec![
"odrefresh".to_string(),
format!("--zygote-arch={}", context.zygote_arch),
format!("--dalvik-cache={}", context.target_dir_name),
- "--no-refresh".to_string(),
format!("--staging-dir={}", staging_dir.display()),
- "--force-compile".to_string(),
+ "--no-refresh".to_string(),
];
+
+ if !context.system_server_compiler_filter.is_empty() {
+ args.push(format!(
+ "--system-server-compiler-filter={}",
+ context.system_server_compiler_filter
+ ));
+ }
+ args.push("--force-compile".to_string());
+
debug!("Running odrefresh with args: {:?}", &args);
let jail = spawn_jailed_task(odrefresh_path, &args, Vec::new() /* fd_mapping */)
.context("Spawn odrefresh")?;
diff --git a/compos/src/compsvc.rs b/compos/src/compsvc.rs
index ef3ae2a..5a2c3ca 100644
--- a/compos/src/compsvc.rs
+++ b/compos/src/compsvc.rs
@@ -101,6 +101,7 @@
staging_dir_fd: i32,
target_dir_name: &str,
zygote_arch: &str,
+ system_server_compiler_filter: &str,
) -> BinderResult<i8> {
let context = to_binder_result(OdrefreshContext::new(
system_dir_fd,
@@ -108,6 +109,7 @@
staging_dir_fd,
target_dir_name,
zygote_arch,
+ system_server_compiler_filter,
))?;
let authfs_service = get_authfs_service()?;
diff --git a/compos/tests/java/android/compos/test/ComposTestCase.java b/compos/tests/java/android/compos/test/ComposTestCase.java
index 7b027de..1e439af 100644
--- a/compos/tests/java/android/compos/test/ComposTestCase.java
+++ b/compos/tests/java/android/compos/test/ComposTestCase.java
@@ -55,9 +55,20 @@
// Files that define the "test" instance of CompOS
private static final String COMPOS_TEST_ROOT = "/data/misc/apexdata/com.android.compos/test/";
+ private static final String SYSTEM_SERVER_COMPILER_FILTER_PROP_NAME =
+ "dalvik.vm.systemservercompilerfilter";
+ private String mBackupSystemServerCompilerFilter;
+
@Before
public void setUp() throws Exception {
testIfDeviceIsCapable(getDevice());
+
+ String value = getDevice().getProperty(SYSTEM_SERVER_COMPILER_FILTER_PROP_NAME);
+ if (value == null) {
+ mBackupSystemServerCompilerFilter = "";
+ } else {
+ mBackupSystemServerCompilerFilter = value;
+ }
}
@After
@@ -71,10 +82,28 @@
// And any artifacts generated by odrefresh
android.tryRun("rm", "-rf", ODREFRESH_OUTPUT_DIR);
+
+ if (mBackupSystemServerCompilerFilter != null) {
+ CLog.d("Restore dalvik.vm.systemservercompilerfilter to "
+ + mBackupSystemServerCompilerFilter);
+ getDevice().setProperty(SYSTEM_SERVER_COMPILER_FILTER_PROP_NAME,
+ mBackupSystemServerCompilerFilter);
+ }
}
@Test
- public void testOdrefresh() throws Exception {
+ public void testOdrefreshSpeed() throws Exception {
+ getDevice().setProperty(SYSTEM_SERVER_COMPILER_FILTER_PROP_NAME, "speed");
+ testOdrefresh();
+ }
+
+ @Test
+ public void testOdrefreshSpeedProfile() throws Exception {
+ getDevice().setProperty(SYSTEM_SERVER_COMPILER_FILTER_PROP_NAME, "speed-profile");
+ testOdrefresh();
+ }
+
+ private void testOdrefresh() throws Exception {
CommandRunner android = new CommandRunner(getDevice());
// Prepare the groundtruth. The compilation on Android should finish successfully.