Merge changes I58337a5b,Ic1fd923d into main

* changes:
  pvmfw: Use AVB VM name as DICE component_name
  pvmfw: Support com.android.virt.name property
diff --git a/android/composd/aidl/android/system/composd/IIsolatedCompilationService.aidl b/android/composd/aidl/android/system/composd/IIsolatedCompilationService.aidl
index 3748899..d7757db 100644
--- a/android/composd/aidl/android/system/composd/IIsolatedCompilationService.aidl
+++ b/android/composd/aidl/android/system/composd/IIsolatedCompilationService.aidl
@@ -35,7 +35,7 @@
      * callback, unless the returned ICompilationTask is cancelled. The caller should maintain
      * a reference to the ICompilationTask until compilation completes or is cancelled.
      */
-    ICompilationTask startStagedApexCompile(ICompilationTaskCallback callback);
+    ICompilationTask startStagedApexCompile(ICompilationTaskCallback callback, String os);
 
     /**
      * Run odrefresh in a test instance of CompOS until completed or failed.
diff --git a/android/composd/src/instance_manager.rs b/android/composd/src/instance_manager.rs
index d1b0b99..a7154ec 100644
--- a/android/composd/src/instance_manager.rs
+++ b/android/composd/src/instance_manager.rs
@@ -39,10 +39,11 @@
         Self { service, state: Default::default() }
     }
 
-    pub fn start_current_instance(&self) -> Result<CompOsInstance> {
+    pub fn start_current_instance(&self, os: &str) -> Result<CompOsInstance> {
         let mut vm_parameters = new_vm_parameters()?;
         vm_parameters.name = String::from("Composd");
         vm_parameters.prefer_staged = true;
+        vm_parameters.os = os.to_owned();
         self.start_instance(CURRENT_INSTANCE_DIR, vm_parameters)
     }
 
diff --git a/android/composd/src/service.rs b/android/composd/src/service.rs
index 3cc40af..1e38eee 100644
--- a/android/composd/src/service.rs
+++ b/android/composd/src/service.rs
@@ -51,9 +51,10 @@
     fn startStagedApexCompile(
         &self,
         callback: &Strong<dyn ICompilationTaskCallback>,
+        os: &str,
     ) -> binder::Result<Strong<dyn ICompilationTask>> {
         check_permissions()?;
-        to_binder_result(self.do_start_staged_apex_compile(callback))
+        to_binder_result(self.do_start_staged_apex_compile(callback, os))
     }
 
     fn startTestCompile(
@@ -76,8 +77,10 @@
     fn do_start_staged_apex_compile(
         &self,
         callback: &Strong<dyn ICompilationTaskCallback>,
+        os: &str,
     ) -> Result<Strong<dyn ICompilationTask>> {
-        let comp_os = self.instance_manager.start_current_instance().context("Starting CompOS")?;
+        let comp_os =
+            self.instance_manager.start_current_instance(os).context("Starting CompOS")?;
 
         let target_dir_name = PENDING_ARTIFACTS_SUBDIR.to_owned();
         let task = OdrefreshTask::start(
diff --git a/android/composd_cmd/composd_cmd.rs b/android/composd_cmd/composd_cmd.rs
index 6281bd0..c944c17 100644
--- a/android/composd_cmd/composd_cmd.rs
+++ b/android/composd_cmd/composd_cmd.rs
@@ -39,7 +39,11 @@
 #[derive(Parser)]
 enum Actions {
     /// Compile classpath for real. Output can be used after a reboot.
-    StagedApexCompile {},
+    StagedApexCompile {
+        /// OS for the VM.
+        #[clap(long, default_value = "microdroid")]
+        os: String,
+    },
 
     /// Compile classpath in a debugging VM. Output is ignored.
     TestCompile {
@@ -59,7 +63,7 @@
     ProcessState::start_thread_pool();
 
     match action {
-        Actions::StagedApexCompile {} => run_staged_apex_compile()?,
+        Actions::StagedApexCompile { os } => run_staged_apex_compile(&os)?,
         Actions::TestCompile { prefer_staged, os } => run_test_compile(prefer_staged, &os)?,
     }
 
@@ -116,8 +120,8 @@
     }
 }
 
-fn run_staged_apex_compile() -> Result<()> {
-    run_async_compilation(|service, callback| service.startStagedApexCompile(callback))
+fn run_staged_apex_compile(os: &str) -> Result<()> {
+    run_async_compilation(|service, callback| service.startStagedApexCompile(callback, os))
 }
 
 fn run_test_compile(prefer_staged: bool, os: &str) -> Result<()> {
diff --git a/android/virtmgr/src/aidl.rs b/android/virtmgr/src/aidl.rs
index 6aecc75..4e17daa 100644
--- a/android/virtmgr/src/aidl.rs
+++ b/android/virtmgr/src/aidl.rs
@@ -421,9 +421,8 @@
 }
 
 fn find_partition(path: Option<&Path>) -> binder::Result<String> {
-    let path = match path {
-        Some(path) => path,
-        None => return Ok("system".to_owned()),
+    let Some(path) = path else {
+        return Ok("system".to_owned());
     };
     if path.starts_with("/system/system_ext/") {
         return Ok("system_ext".to_owned());
@@ -431,36 +430,30 @@
         return Ok("product".to_owned());
     }
     let mut components = path.components();
-    match components.nth(1) {
-        Some(std::path::Component::Normal(partition)) => {
-            if partition != "apex" {
-                return Ok(partition.to_string_lossy().into_owned());
-            }
+    let Some(std::path::Component::Normal(partition)) = components.nth(1) else {
+        return Err(anyhow!("Can't find partition in '{}'", path.display()))
+            .or_service_specific_exception(-1);
+    };
 
-            // If path is under /apex, find a partition of the preinstalled .apex path
-            let apex_name = match components.next() {
-                Some(std::path::Component::Normal(name)) => name.to_string_lossy(),
-                _ => {
-                    return Err(anyhow!("Can't find apex name for '{}'", path.display()))
-                        .or_service_specific_exception(-1)
-                }
-            };
-
-            let apex_info_list = ApexInfoList::load()
-                .context("Failed to get apex info list")
-                .or_service_specific_exception(-1)?;
-
-            for apex_info in apex_info_list.list.iter() {
-                if apex_info.name == apex_name {
-                    return Ok(apex_info.partition.to_lowercase());
-                }
-            }
-
-            Err(anyhow!("Can't find apex info for '{apex_name}'")).or_service_specific_exception(-1)
-        }
-        _ => Err(anyhow!("Can't find partition in '{}'", path.display()))
-            .or_service_specific_exception(-1),
+    // If path is under /apex, find a partition of the preinstalled .apex path
+    if partition == "apex" {
+        let Some(std::path::Component::Normal(apex_name)) = components.next() else {
+            return Err(anyhow!("Can't find apex name for '{}'", path.display()))
+                .or_service_specific_exception(-1);
+        };
+        let apex_info_list = ApexInfoList::load()
+            .context("Failed to get apex info list")
+            .or_service_specific_exception(-1)?;
+        return apex_info_list
+            .list
+            .iter()
+            .find(|apex_info| apex_info.name.as_str() == apex_name)
+            .map(|apex_info| apex_info.partition.to_lowercase())
+            .ok_or(anyhow!("Can't find apex info for {apex_name:?}"))
+            .or_service_specific_exception(-1);
     }
+
+    Ok(partition.to_string_lossy().into_owned())
 }
 
 impl VirtualizationService {
diff --git a/android/virtmgr/src/crosvm.rs b/android/virtmgr/src/crosvm.rs
index 8500421..9ee181a 100644
--- a/android/virtmgr/src/crosvm.rs
+++ b/android/virtmgr/src/crosvm.rs
@@ -628,6 +628,7 @@
 
     fn monitor_vm_status(&self, child: Arc<SharedChild>) {
         let pid = child.id();
+        let mut metric_countdown = 0;
 
         loop {
             {
@@ -637,23 +638,34 @@
                     break;
                 }
 
-                let mut vm_metric = self.vm_metric.lock().unwrap();
+                if metric_countdown > 0 {
+                    metric_countdown -= 1;
+                } else {
+                    metric_countdown = 10;
+                    let mut vm_metric = self.vm_metric.lock().unwrap();
 
-                // Get CPU Information
-                match get_guest_time(pid) {
-                    Ok(guest_time) => vm_metric.cpu_guest_time = Some(guest_time),
-                    Err(e) => error!("Failed to get guest CPU time: {e:?}"),
-                }
-
-                // Get Memory Information
-                match get_rss(pid) {
-                    Ok(rss) => {
-                        vm_metric.rss = match &vm_metric.rss {
-                            Some(x) => Some(Rss::extract_max(x, &rss)),
-                            None => Some(rss),
+                    // Get CPU Information
+                    match get_guest_time(pid) {
+                        Ok(guest_time) => vm_metric.cpu_guest_time = Some(guest_time),
+                        Err(e) => {
+                            metric_countdown = 0;
+                            error!("Failed to get guest CPU time: {e:?}");
                         }
                     }
-                    Err(e) => error!("Failed to get guest RSS: {}", e),
+
+                    // Get Memory Information
+                    match get_rss(pid) {
+                        Ok(rss) => {
+                            vm_metric.rss = match &vm_metric.rss {
+                                Some(x) => Some(Rss::extract_max(x, &rss)),
+                                None => Some(rss),
+                            }
+                        }
+                        Err(e) => {
+                            metric_countdown = 0;
+                            error!("Failed to get guest RSS: {}", e);
+                        }
+                    }
                 }
             }
 
diff --git a/build/debian/build.sh b/build/debian/build.sh
index 6facfcf..616dd00 100755
--- a/build/debian/build.sh
+++ b/build/debian/build.sh
@@ -269,7 +269,7 @@
 	            --extract "${dsc_file}"
 	pushd "linux-${debian_kver%-*}" > /dev/null
 
-	local kpatches_src="$SCRIPT_DIR/kernel_patches"
+	local kpatches_src="$SCRIPT_DIR/kernel/patches"
 	cp -r "${kpatches_src}/avf" debian/patches/
 	cat "${kpatches_src}/series" >> debian/patches/series
 	./debian/rules orig
@@ -282,9 +282,8 @@
 
 	# 2. Define our custom flavour and regenerate control file
 	# NOTE: Our flavour extends Debian's `cloud` config on the `none` featureset.
-	cat > debian/config/${debian_arch}/config.${debarch_flavour} <<EOF
-# TODO: Add our custom kernel config to this file
-EOF
+	cp "$SCRIPT_DIR/kernel/config" \
+	   debian/config/${debian_arch}/config.${debarch_flavour}
 
 	sed -z "s;\[base\]\nflavours:;[base]\nflavours:\n ${debarch_flavour};" \
 	    -i debian/config/${debian_arch}/none/defines
diff --git a/build/debian/fai_config/files/usr/local/bin/enable_display/AVF b/build/debian/fai_config/files/usr/local/bin/enable_display/AVF
index 69dce6a..76f9f97 100644
--- a/build/debian/fai_config/files/usr/local/bin/enable_display/AVF
+++ b/build/debian/fai_config/files/usr/local/bin/enable_display/AVF
@@ -1,4 +1,6 @@
 #!/bin/bash
 sudo systemd-run --collect -E XDG_SESSION_TYPE=wayland --uid=1000 -p PAMName=login -p TTYPath=/dev/tty7 sleep 1d
 systemctl --user start weston
-export DISPLAY=:0
\ No newline at end of file
+export DISPLAY=:0
+export MESA_LOADER_DRIVER_OVERRIDE=zink
+export LIBGL_ALWAYS_SOFTWARE=1
\ No newline at end of file
diff --git a/build/debian/fai_config/scripts/AVF/20-useradd b/build/debian/fai_config/scripts/AVF/20-useradd
index 1c93772..b92648a 100755
--- a/build/debian/fai_config/scripts/AVF/20-useradd
+++ b/build/debian/fai_config/scripts/AVF/20-useradd
@@ -1,4 +1,4 @@
 #!/bin/bash
 
-$ROOTCMD useradd -m -u 1000 -N -G sudo -s /usr/bin/bash droid
+$ROOTCMD useradd -m -u 1000 -N -G sudo,video,render -s /usr/bin/bash droid
 $ROOTCMD echo 'droid ALL=(ALL) NOPASSWD:ALL' >> $target/etc/sudoers
diff --git a/build/debian/kernel/config b/build/debian/kernel/config
new file mode 100644
index 0000000..1ba603c
--- /dev/null
+++ b/build/debian/kernel/config
@@ -0,0 +1 @@
+CONFIG_DRM=m
diff --git a/build/debian/kernel_patches/avf/arm64-balloon.patch b/build/debian/kernel/patches/avf/arm64-balloon.patch
similarity index 100%
rename from build/debian/kernel_patches/avf/arm64-balloon.patch
rename to build/debian/kernel/patches/avf/arm64-balloon.patch
diff --git a/build/debian/kernel_patches/series b/build/debian/kernel/patches/series
similarity index 100%
rename from build/debian/kernel_patches/series
rename to build/debian/kernel/patches/series
diff --git a/build/debian/vm_config.json.aarch64 b/build/debian/vm_config.json.aarch64
index 96254f8..463583f 100644
--- a/build/debian/vm_config.json.aarch64
+++ b/build/debian/vm_config.json.aarch64
@@ -35,5 +35,8 @@
     "console_out": true,
     "console_input_device": "ttyS0",
     "network": true,
-    "auto_memory_balloon": true
+    "auto_memory_balloon": true,
+    "gpu": {
+        "backend": "2d"
+    }
 }
diff --git a/build/debian/vm_config.json.x86_64 b/build/debian/vm_config.json.x86_64
index c34a0f2..bc4e00a 100644
--- a/build/debian/vm_config.json.x86_64
+++ b/build/debian/vm_config.json.x86_64
@@ -44,5 +44,8 @@
     "console_out": true,
     "console_input_device": "ttyS0",
     "network": true,
-    "auto_memory_balloon": true
+    "auto_memory_balloon": true,
+    "gpu": {
+        "backend": "2d"
+    }
 }
diff --git a/guest/authfs/Android.bp b/guest/authfs/Android.bp
index 28e0f4a..6c229b6 100644
--- a/guest/authfs/Android.bp
+++ b/guest/authfs/Android.bp
@@ -26,13 +26,12 @@
         "libthiserror",
     ],
     prefer_rlib: true,
-    target: {
-        darwin: {
+    multilib: {
+        lib32: {
             enabled: false,
         },
     },
     defaults: [
-        "crosvm_defaults",
         "avf_build_flags_rust",
     ],
 }
@@ -47,8 +46,4 @@
 rust_binary {
     name: "authfs",
     defaults: ["authfs_defaults"],
-    // //apex_available:platform is necessary here to counteract the
-    // com.android.virt in crosvm_defaults and make authfs available
-    // to the platform so it can be embedded in the microdroid image.
-    apex_available: ["//apex_available:platform"],
 }
diff --git a/guest/shutdown_runner/debian/service b/guest/shutdown_runner/debian/service
index d19ff25..7188d36 100644
--- a/guest/shutdown_runner/debian/service
+++ b/guest/shutdown_runner/debian/service
@@ -6,6 +6,8 @@
 [Service]
 ExecStart=/usr/bin/bash -c '/usr/bin/shutdown_runner --grpc_port $(cat /mnt/internal/debian_service_port)'
 Type=simple
+Restart=on-failure
+RestartSec=1
 User=root
 Group=root
 
diff --git a/guest/trusty/security_vm/vm/Android.bp b/guest/trusty/security_vm/vm/Android.bp
index d823448..a348699 100644
--- a/guest/trusty/security_vm/vm/Android.bp
+++ b/guest/trusty/security_vm/vm/Android.bp
@@ -95,6 +95,7 @@
         ":security_vm.S",
     ],
     crt: false,
+    static_libs: ["trusty_security_vm_signed_bin"],
     system_shared_libs: [],
     visibility: ["//visibility:private"],
     enabled: select((os(), arch(), soong_config_variable("trusty_system_vm", "enabled")), {
diff --git a/guest/trusty/test_vm/vm/Android.bp b/guest/trusty/test_vm/vm/Android.bp
index 1db9078..4f696b1 100644
--- a/guest/trusty/test_vm/vm/Android.bp
+++ b/guest/trusty/test_vm/vm/Android.bp
@@ -78,6 +78,7 @@
         ":test_vm.S",
     ],
     crt: false,
+    static_libs: ["trusty_test_vm_signed_bin"],
     system_shared_libs: [],
     enabled: false,
     target: {
diff --git a/libs/framework-virtualization/src/android/system/virtualmachine/VirtualMachine.java b/libs/framework-virtualization/src/android/system/virtualmachine/VirtualMachine.java
index 5f634ef..af313a1 100644
--- a/libs/framework-virtualization/src/android/system/virtualmachine/VirtualMachine.java
+++ b/libs/framework-virtualization/src/android/system/virtualmachine/VirtualMachine.java
@@ -276,28 +276,16 @@
 
         @Override
         public void onTrimMemory(int level) {
-            int percent;
+            /* Treat level < TRIM_MEMORY_UI_HIDDEN as generic low-memory warnings */
+            int percent = 10;
 
-            switch (level) {
-                case ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL:
-                    percent = 50;
-                    break;
-                case ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW:
-                    percent = 30;
-                    break;
-                case ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE:
-                    percent = 10;
-                    break;
-                case ComponentCallbacks2.TRIM_MEMORY_BACKGROUND:
-                case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
-                case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
-                    /* Release as much memory as we can. The app is on the LMKD LRU kill list. */
-                    percent = 50;
-                    break;
-                default:
-                    /* Treat unrecognised messages as generic low-memory warnings. */
-                    percent = 30;
-                    break;
+            if (level >= ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) {
+                percent = 30;
+            }
+
+            if (level >= ComponentCallbacks2.TRIM_MEMORY_BACKGROUND) {
+                /* Release as much memory as we can. The app is on the LMKD LRU kill list. */
+                percent = 50;
             }
 
             synchronized (mLock) {
diff --git a/libs/framework-virtualization/src/android/system/virtualmachine/VirtualMachineConfig.java b/libs/framework-virtualization/src/android/system/virtualmachine/VirtualMachineConfig.java
index 83b234d..2668ca2 100644
--- a/libs/framework-virtualization/src/android/system/virtualmachine/VirtualMachineConfig.java
+++ b/libs/framework-virtualization/src/android/system/virtualmachine/VirtualMachineConfig.java
@@ -42,6 +42,7 @@
 import android.sysprop.HypervisorProperties;
 import android.system.virtualizationservice.AssignedDevices;
 import android.system.virtualizationservice.CpuOptions;
+import android.system.virtualizationservice.CustomMemoryBackingFile;
 import android.system.virtualizationservice.DiskImage;
 import android.system.virtualizationservice.Partition;
 import android.system.virtualizationservice.SharedPath;
@@ -835,6 +836,7 @@
                                 })
                         .orElse(null);
         config.teeServices = EMPTY_STRING_ARRAY;
+        config.customMemoryBackingFiles = new CustomMemoryBackingFile[0];
         return config;
     }
 
diff --git a/libs/service-compos/java/com/android/server/compos/IsolatedCompilationJobService.java b/libs/service-compos/java/com/android/server/compos/IsolatedCompilationJobService.java
index adc0300..3033991 100644
--- a/libs/service-compos/java/com/android/server/compos/IsolatedCompilationJobService.java
+++ b/libs/service-compos/java/com/android/server/compos/IsolatedCompilationJobService.java
@@ -174,7 +174,7 @@
             }
 
             try {
-                ICompilationTask composTask = composd.startStagedApexCompile(this);
+                ICompilationTask composTask = composd.startStagedApexCompile(this, "microdroid");
                 mMetrics.onCompilationStarted();
                 mTask.set(composTask);
                 composTask.asBinder().linkToDeath(this, 0);
diff --git a/tests/backcompat_test/src/main.rs b/tests/backcompat_test/src/main.rs
index 4d09a89..b92049d 100644
--- a/tests/backcompat_test/src/main.rs
+++ b/tests/backcompat_test/src/main.rs
@@ -25,7 +25,6 @@
 use anyhow::anyhow;
 use anyhow::Context;
 use anyhow::Error;
-use log::error;
 use log::info;
 use std::fs::read_to_string;
 use std::fs::File;
@@ -188,15 +187,15 @@
             return Err(anyhow!("failed to execute dtc"));
         }
         let dt2 = read_to_string("dump_dt_failed.dts")?;
-        error!(
+        eprintln!(
             "Device tree 2 does not match golden DT.\n
                Device Tree 2: {}",
             dt2
         );
         return Err(anyhow!(
-            "stdout: {:?}\n stderr: {:?}",
-            dtcompare_res.stdout,
-            dtcompare_res.stderr
+            "stdout: {}\n stderr: {}",
+            String::from_utf8_lossy(&dtcompare_res.stdout),
+            String::from_utf8_lossy(&dtcompare_res.stderr)
         ));
     }
 
diff --git a/tests/benchmark_hostside/java/android/avf/test/AVFHostTestCase.java b/tests/benchmark_hostside/java/android/avf/test/AVFHostTestCase.java
index e2956f2..003c3f0 100644
--- a/tests/benchmark_hostside/java/android/avf/test/AVFHostTestCase.java
+++ b/tests/benchmark_hostside/java/android/avf/test/AVFHostTestCase.java
@@ -19,6 +19,7 @@
 import static com.android.tradefed.device.TestDevice.MicrodroidBuilder;
 import static com.android.tradefed.testtype.DeviceJUnit4ClassRunner.TestMetrics;
 
+import static com.google.common.truth.Truth.assertThat;
 import static com.google.common.truth.Truth.assertWithMessage;
 import static com.google.common.truth.TruthJUnit.assume;
 
@@ -113,16 +114,78 @@
 
     @Test
     public void testBootWithCompOS() throws Exception {
-        composTestHelper(true);
+        composTestHelper(true, "microdroid");
+    }
+
+    @Test
+    public void testBootWithCompOS_os_android15_66() throws Exception {
+        composTestHelper(true, "android15_66");
+    }
+
+    @Test
+    public void testBootWithCompOS_os_microdroid_16k() throws Exception {
+        composTestHelper(true, "microdroid_16k");
     }
 
     @Test
     public void testBootWithoutCompOS() throws Exception {
-        composTestHelper(false);
+        composTestHelper(false, null);
     }
 
     @Test
     public void testNoLongHypSections() throws Exception {
+        noLongHypSectionsHelper("microdroid");
+    }
+
+    @Test
+    public void testNoLongHypSections_os_android15_66() throws Exception {
+        noLongHypSectionsHelper("android15_66");
+    }
+
+    @Test
+    public void testNoLongHypSections_os_microdroid_16k() throws Exception {
+        noLongHypSectionsHelper("microdroid_16k");
+    }
+
+    @Test
+    public void testPsciMemProtect() throws Exception {
+        psciMemProtectHelper("microdroid");
+    }
+
+    @Test
+    public void testPsciMemProtect_os_android15_66() throws Exception {
+        psciMemProtectHelper("android15_66");
+    }
+
+    @Test
+    public void testPsciMemProtect_os_microdroid_16k() throws Exception {
+        psciMemProtectHelper("microdroid_16k");
+    }
+
+    @Test
+    public void testCameraAppStartupTime() throws Exception {
+        String[] launchIntentPackages = {
+            "com.android.camera2",
+            "com.google.android.GoogleCamera/com.android.camera.CameraLauncher"
+        };
+        String launchIntentPackage = findSupportedPackage(launchIntentPackages);
+        assume().withMessage("No supported camera package").that(launchIntentPackage).isNotNull();
+        appStartupHelper(launchIntentPackage);
+    }
+
+    @Test
+    public void testSettingsAppStartupTime() throws Exception {
+        String[] launchIntentPackages = {"com.android.settings"};
+        String launchIntentPackage = findSupportedPackage(launchIntentPackages);
+        assume().withMessage("No supported settings package").that(launchIntentPackage).isNotNull();
+        appStartupHelper(launchIntentPackage);
+    }
+
+    private void noLongHypSectionsHelper(String osKey) throws Exception {
+        assumeKernelSupported(osKey);
+        assumeVmTypeSupported(osKey, true);
+        String os = SUPPORTED_OSES.get(osKey);
+
         String[] hypEvents = {"hyp_enter", "hyp_exit"};
 
         assumeTrue(
@@ -130,7 +193,7 @@
                 KvmHypTracer.isSupported(getDevice(), hypEvents));
 
         KvmHypTracer tracer = new KvmHypTracer(getDevice(), hypEvents);
-        String result = tracer.run(COMPOSD_CMD_BIN + " test-compile");
+        String result = tracer.run(COMPOSD_CMD_BIN + " test-compile --os " + os);
         assertWithMessage("Failed to test compilation VM.")
                 .that(result)
                 .ignoringCase()
@@ -141,8 +204,11 @@
         CLog.i("Hypervisor traces parsed successfully.");
     }
 
-    @Test
-    public void testPsciMemProtect() throws Exception {
+    public void psciMemProtectHelper(String osKey) throws Exception {
+        assumeKernelSupported(osKey);
+        assumeVmTypeSupported(osKey, true);
+        String os = SUPPORTED_OSES.get(osKey);
+
         String[] hypEvents = {"psci_mem_protect"};
 
         assumeTrue(
@@ -151,7 +217,12 @@
         KvmHypTracer tracer = new KvmHypTracer(getDevice(), hypEvents);
 
         /* We need to wait for crosvm to die so all the VM pages are reclaimed */
-        String result = tracer.run(COMPOSD_CMD_BIN + " test-compile && killall -w crosvm || true");
+        String result =
+                tracer.run(
+                        COMPOSD_CMD_BIN
+                                + " test-compile --os "
+                                + os
+                                + " && killall -w crosvm || true");
         assertWithMessage("Failed to test compilation VM.")
                 .that(result)
                 .ignoringCase()
@@ -176,25 +247,6 @@
                 .isGreaterThan(0);
     }
 
-    @Test
-    public void testCameraAppStartupTime() throws Exception {
-        String[] launchIntentPackages = {
-            "com.android.camera2",
-            "com.google.android.GoogleCamera/com.android.camera.CameraLauncher"
-        };
-        String launchIntentPackage = findSupportedPackage(launchIntentPackages);
-        assume().withMessage("No supported camera package").that(launchIntentPackage).isNotNull();
-        appStartupHelper(launchIntentPackage);
-    }
-
-    @Test
-    public void testSettingsAppStartupTime() throws Exception {
-        String[] launchIntentPackages = {"com.android.settings"};
-        String launchIntentPackage = findSupportedPackage(launchIntentPackages);
-        assume().withMessage("No supported settings package").that(launchIntentPackage).isNotNull();
-        appStartupHelper(launchIntentPackage);
-    }
-
     private void appStartupHelper(String launchIntentPackage) throws Exception {
         assumeTrue(
                 "Skip on non-protected VMs",
@@ -471,8 +523,14 @@
         throw new IllegalArgumentException("Failed to get boot time info.");
     }
 
-    private void composTestHelper(boolean isWithCompos) throws Exception {
+    private void composTestHelper(boolean isWithCompos, String osKey) throws Exception {
         assumeFalse("Skip on CF; too slow", isCuttlefish());
+        if (isWithCompos) {
+            assumeKernelSupported(osKey);
+            assumeVmTypeSupported(osKey, true);
+        } else {
+            assertThat(osKey).isNull();
+        }
 
         List<Double> bootDmesgTime = new ArrayList<>(ROUND_COUNT);
 
@@ -480,7 +538,8 @@
             reInstallApex(REINSTALL_APEX_TIMEOUT_SEC);
             try {
                 if (isWithCompos) {
-                    compileStagedApex(COMPILE_STAGED_APEX_TIMEOUT_SEC);
+                    String os = SUPPORTED_OSES.get(osKey);
+                    compileStagedApex(COMPILE_STAGED_APEX_TIMEOUT_SEC, os);
                 }
             } finally {
                 // If compilation fails, we still have a staged APEX, and we need to reboot to
@@ -518,7 +577,7 @@
         getDevice().enableAdbRoot();
     }
 
-    private void compileStagedApex(int timeoutSec) throws Exception {
+    private void compileStagedApex(int timeoutSec, String os) throws Exception {
 
         long timeStart = System.currentTimeMillis();
         long timeEnd = timeStart + timeoutSec * 1000L;
@@ -530,7 +589,7 @@
 
                 String result =
                         android.runWithTimeout(
-                                3 * 60 * 1000, COMPOSD_CMD_BIN + " staged-apex-compile");
+                                3 * 60 * 1000, COMPOSD_CMD_BIN + " staged-apex-compile --os " + os);
                 assertWithMessage("Failed to compile staged APEX. Reason: " + result)
                         .that(result)
                         .ignoringCase()
diff --git a/tests/hostside/helper/java/com/android/microdroid/test/host/MicrodroidHostTestCaseBase.java b/tests/hostside/helper/java/com/android/microdroid/test/host/MicrodroidHostTestCaseBase.java
index ad37dda..fcef19a 100644
--- a/tests/hostside/helper/java/com/android/microdroid/test/host/MicrodroidHostTestCaseBase.java
+++ b/tests/hostside/helper/java/com/android/microdroid/test/host/MicrodroidHostTestCaseBase.java
@@ -18,6 +18,7 @@
 
 import static com.android.tradefed.testtype.DeviceJUnit4ClassRunner.TestLogData;
 
+import static com.google.common.truth.Truth.assertThat;
 import static com.google.common.truth.Truth.assertWithMessage;
 
 import static org.junit.Assume.assumeFalse;
@@ -267,4 +268,27 @@
     protected boolean isPkvmHypervisor() throws DeviceNotAvailableException {
         return "kvm.arm-protected".equals(getDevice().getProperty("ro.boot.hypervisor.version"));
     }
+
+    protected TestDevice getAndroidDevice() {
+        TestDevice androidDevice = (TestDevice) getDevice();
+        assertThat(androidDevice).isNotNull();
+        return androidDevice;
+    }
+
+    protected void assumeKernelSupported(String osKey) throws Exception {
+        String os = SUPPORTED_OSES.get(osKey);
+        assumeTrue(
+                "Skipping test as OS \"" + os + "\" is not supported",
+                getSupportedOSList().contains(os));
+    }
+
+    protected void assumeVmTypeSupported(String os, boolean protectedVm) throws Exception {
+        // TODO(b/376870129): remove this check
+        if (protectedVm) {
+            assumeFalse("pVMs with 16k kernel are not supported yet :(", os.endsWith("_16k"));
+        }
+        assumeTrue(
+                "Microdroid is not supported for specific VM protection type",
+                getAndroidDevice().supportsMicrodroid(protectedVm));
+    }
 }
diff --git a/tests/hostside/java/com/android/microdroid/test/MicrodroidHostTests.java b/tests/hostside/java/com/android/microdroid/test/MicrodroidHostTests.java
index 7864f3f..59a57f1 100644
--- a/tests/hostside/java/com/android/microdroid/test/MicrodroidHostTests.java
+++ b/tests/hostside/java/com/android/microdroid/test/MicrodroidHostTests.java
@@ -1474,12 +1474,6 @@
         }
     }
 
-    private TestDevice getAndroidDevice() {
-        TestDevice androidDevice = (TestDevice) getDevice();
-        assertThat(androidDevice).isNotNull();
-        return androidDevice;
-    }
-
     // The TradeFed Dockerfile sets LD_LIBRARY_PATH to a directory with an older libc++.so, which
     // breaks binaries that are linked against a newer libc++.so. Binaries commonly use DT_RUNPATH
     // to find an adjacent libc++.so (e.g. `$ORIGIN/../lib64`), but LD_LIBRARY_PATH overrides
@@ -1490,23 +1484,6 @@
         return runUtil;
     }
 
-    private void assumeKernelSupported(String osKey) throws Exception {
-        String os = SUPPORTED_OSES.get(osKey);
-        assumeTrue(
-                "Skipping test as OS \"" + os + "\" is not supported",
-                getSupportedOSList().contains(os));
-    }
-
-    private void assumeVmTypeSupported(String os, boolean protectedVm) throws Exception {
-        // TODO(b/376870129): remove this check
-        if (protectedVm) {
-            assumeFalse("pVMs with 16k kernel are not supported yet :(", os.endsWith("_16k"));
-        }
-        assumeTrue(
-                "Microdroid is not supported for specific VM protection type",
-                getAndroidDevice().supportsMicrodroid(protectedVm));
-    }
-
     private void assumeArm64Supported() throws Exception {
         CommandRunner android = new CommandRunner(getDevice());
         String abi = android.run("getprop", "ro.product.cpu.abi");