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/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()?;