Add preparing custom pvmfw for hostside test

Bug: 243672257
Test: atest com.android.microdroid.test.MicrodroidHostTests -- \
  --module-arg MicrodroidHostTestCases:set-option:pvmfw:pvmfw.img
Change-Id: Ie802b864cdf7f72d123e938e372d4e03881da6e8
diff --git a/docs/getting_started/index.md b/docs/getting_started/index.md
index 7055a65..c98810b 100644
--- a/docs/getting_started/index.md
+++ b/docs/getting_started/index.md
@@ -97,6 +97,15 @@
 If you run into problems, inspect the logs produced by `atest`. Their location is printed at the
 end. The `host_log_*.zip` file should contain the output of individual commands as well as VM logs.
 
+### Custom pvmfw
+
+Hostside tests, which run on the PC and extends `MicrodroidHostTestCaseBase`, can be run with
+a custom `pvmfw`. Use `--module-arg` to push `pvmfw` for individual test methods.
+
+```shell
+atest com.android.microdroid.test.MicrodroidHostTests -- --module-arg MicrodroidHostTestCases:set-option:pvmfw:pvmfw.img
+```
+
 ## Spawning your own VMs with custom kernel
 
 You can spawn your own VMs by passing a JSON config file to the VirtualizationService via the `vm`
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 e5aa908..8816dbd 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
@@ -29,6 +29,7 @@
 import com.android.microdroid.test.common.DeviceProperties;
 import com.android.microdroid.test.common.MetricsProcessor;
 import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.config.Option;
 import com.android.tradefed.device.DeviceNotAvailableException;
 import com.android.tradefed.device.ITestDevice;
 import com.android.tradefed.device.TestDevice;
@@ -41,12 +42,15 @@
 import java.util.Arrays;
 
 public abstract class MicrodroidHostTestCaseBase extends BaseHostJUnit4Test {
+
     protected static final String TEST_ROOT = "/data/local/tmp/virt/";
     protected static final String LOG_PATH = TEST_ROOT + "log.txt";
     protected static final String CONSOLE_PATH = TEST_ROOT + "console.txt";
     private static final int TEST_VM_ADB_PORT = 8000;
     private static final String MICRODROID_SERIAL = "localhost:" + TEST_VM_ADB_PORT;
     private static final String INSTANCE_IMG = "instance.img";
+    private static final String PVMFW_IMG_PATH = TEST_ROOT + "pvmfw.img";
+    private static final String PVMFW_IMG_PATH_PROP = "hypervisor.pvmfw.path";
 
     private static final long MICRODROID_ADB_CONNECT_TIMEOUT_MINUTES = 5;
     protected static final long MICRODROID_COMMAND_TIMEOUT_MILLIS = 30000;
@@ -55,6 +59,19 @@
             (int) (MICRODROID_ADB_CONNECT_TIMEOUT_MINUTES * 60 * 1000
                 / MICRODROID_COMMAND_RETRY_INTERVAL_MILLIS);
 
+    @Option(
+            name = "pvmfw",
+            description =
+                    "Custom pvmfw.img path on host device."
+                            + " If present, it will be pushed to "
+                            + PVMFW_IMG_PATH,
+            mandatory = false)
+    private static String sCustomPvmfwPathOnHost = "";
+
+    private static boolean isEmptyText(String str) {
+        return str == null || str.length() == 0;
+    }
+
     public static void prepareVirtualizationTestSetup(ITestDevice androidDevice)
             throws DeviceNotAvailableException {
         CommandRunner android = new CommandRunner(androidDevice);
@@ -67,6 +84,13 @@
 
         // remove any leftover files under test root
         android.tryRun("rm", "-rf", TEST_ROOT + "*");
+
+        // prepare custom pvmfw.img if necessary
+        if (!isEmptyText(sCustomPvmfwPathOnHost)) {
+            runOnHost("adb", "root");
+            runOnHost("adb", "push", sCustomPvmfwPathOnHost, PVMFW_IMG_PATH);
+            runOnHost("adb", "shell", "setprop", PVMFW_IMG_PATH_PROP, PVMFW_IMG_PATH);
+        }
     }
 
     public static void cleanUpVirtualizationTestSetup(ITestDevice androidDevice)
@@ -80,6 +104,10 @@
         android.tryRun("killall", "crosvm");
         android.tryRun("stop", "virtualizationservice");
         android.tryRun("rm", "-rf", "/data/misc/virtualizationservice/*");
+
+        if (!isEmptyText(sCustomPvmfwPathOnHost)) {
+            runOnHost("adb", "shell", "setprop", PVMFW_IMG_PATH_PROP, "\"\"");
+        }
     }
 
     protected boolean isCuttlefish() {