Merge "Allow setting APK path explicitly"
diff --git a/javalib/src/android/system/virtualmachine/VirtualMachineConfig.java b/javalib/src/android/system/virtualmachine/VirtualMachineConfig.java
index d8ff8c6..9555d1e 100644
--- a/javalib/src/android/system/virtualmachine/VirtualMachineConfig.java
+++ b/javalib/src/android/system/virtualmachine/VirtualMachineConfig.java
@@ -18,6 +18,8 @@
import static android.os.ParcelFileDescriptor.MODE_READ_ONLY;
+import static java.util.Objects.requireNonNull;
+
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -57,7 +59,7 @@
private static final String KEY_MEMORY_MIB = "memoryMib";
private static final String KEY_NUM_CPUS = "numCpus";
- // Paths to the APK file of this application.
+ // Absolute path to the APK file containing the VM payload.
@NonNull private final String mApkPath;
/** @hide */
@@ -128,7 +130,11 @@
boolean protectedVm,
int memoryMib,
int numCpus) {
- mApkPath = Objects.requireNonNull(apkPath);
+ requireNonNull(apkPath);
+ if (!apkPath.startsWith("/")) {
+ throw new IllegalArgumentException("APK path must be an absolute path");
+ }
+ mApkPath = apkPath;
mPayloadConfigPath = payloadConfigPath;
mPayloadBinaryPath = payloadBinaryPath;
mDebugLevel = debugLevel;
@@ -188,6 +194,17 @@
}
/**
+ * Returns the absolute path of the APK which should contain the binary payload that will
+ * execute within the VM.
+ *
+ * @hide
+ */
+ @NonNull
+ public String getApkPath() {
+ return mApkPath;
+ }
+
+ /**
* Returns the path to the payload config within the owning application.
*
* @hide
@@ -307,6 +324,7 @@
*/
public static final class Builder {
private final Context mContext;
+ @Nullable private String mApkPath;
@Nullable private String mPayloadConfigPath;
@Nullable private String mPayloadBinaryPath;
@DebugLevel private int mDebugLevel;
@@ -321,7 +339,7 @@
* @hide
*/
public Builder(@NonNull Context context) {
- mContext = Objects.requireNonNull(context);
+ mContext = requireNonNull(context);
mDebugLevel = DEBUG_LEVEL_NONE;
mNumCpus = 1;
}
@@ -333,9 +351,9 @@
*/
@NonNull
public VirtualMachineConfig build() {
- final String apkPath = mContext.getPackageCodePath();
+ String apkPath = (mApkPath == null) ? mContext.getPackageCodePath() : mApkPath;
- final int availableCpus = Runtime.getRuntime().availableProcessors();
+ int availableCpus = Runtime.getRuntime().availableProcessors();
if (mNumCpus < 1 || mNumCpus > availableCpus) {
throw new IllegalArgumentException("Number of vCPUs (" + mNumCpus + ") is out of "
+ "range [1, " + availableCpus + "]");
@@ -372,6 +390,18 @@
}
/**
+ * Sets the absolute path of the APK containing the binary payload that will execute within
+ * the VM. If not set explicitly, defaults to the primary APK of the context.
+ *
+ * @hide
+ */
+ @NonNull
+ public Builder setApkPath(@NonNull String apkPath) {
+ mApkPath = requireNonNull(apkPath);
+ return this;
+ }
+
+ /**
* Sets the path within the APK to the payload config file that defines software aspects
* of the VM.
*
@@ -380,7 +410,7 @@
@RequiresPermission(VirtualMachine.USE_CUSTOM_VIRTUAL_MACHINE_PERMISSION)
@NonNull
public Builder setPayloadConfigPath(@NonNull String payloadConfigPath) {
- mPayloadConfigPath = Objects.requireNonNull(payloadConfigPath);
+ mPayloadConfigPath = requireNonNull(payloadConfigPath);
return this;
}
@@ -392,7 +422,7 @@
*/
@NonNull
public Builder setPayloadBinaryPath(@NonNull String payloadBinaryPath) {
- mPayloadBinaryPath = Objects.requireNonNull(payloadBinaryPath);
+ mPayloadBinaryPath = requireNonNull(payloadBinaryPath);
return this;
}
diff --git a/tests/testapk/src/java/com/android/microdroid/test/MicrodroidTests.java b/tests/testapk/src/java/com/android/microdroid/test/MicrodroidTests.java
index c4296df..e5052bf 100644
--- a/tests/testapk/src/java/com/android/microdroid/test/MicrodroidTests.java
+++ b/tests/testapk/src/java/com/android/microdroid/test/MicrodroidTests.java
@@ -158,6 +158,39 @@
.contains("android.permission.USE_CUSTOM_VIRTUAL_MACHINE permission");
}
+ @Test
+ @CddTest(requirements = {
+ "9.17/C-1-1",
+ })
+ public void validApkPathIsAccepted() throws Exception {
+ assumeSupportedKernel();
+
+ VirtualMachineConfig config = mInner.newVmConfigBuilder()
+ .setPayloadBinaryPath("MicrodroidTestNativeLib.so")
+ .setApkPath(getContext().getPackageCodePath())
+ .setMemoryMib(minMemoryRequired())
+ .build();
+
+ VirtualMachine vm = mInner.forceCreateNewVirtualMachine(
+ "test_vm_explicit_apk_path", config);
+
+ TestResults testResults = runVmTestService(vm);
+ assertThat(testResults.mException).isNull();
+ }
+
+ @Test
+ @CddTest(requirements = {
+ "9.17/C-1-1",
+ })
+ public void invalidApkPathIsRejected() {
+ assumeSupportedKernel();
+
+ VirtualMachineConfig.Builder builder = mInner.newVmConfigBuilder()
+ .setPayloadBinaryPath("MicrodroidTestNativeLib.so")
+ .setApkPath("relative/path/to.apk")
+ .setMemoryMib(minMemoryRequired());
+ assertThrows(IllegalArgumentException.class, () -> builder.build());
+ }
@Test
@CddTest(requirements = {