Merge "[release] Add more check for rialto resigning" into main
diff --git a/authfs/tests/common/src/java/com/android/fs/common/AuthFsTestRule.java b/authfs/tests/common/src/java/com/android/fs/common/AuthFsTestRule.java
index 7c85797..9c0fd72 100644
--- a/authfs/tests/common/src/java/com/android/fs/common/AuthFsTestRule.java
+++ b/authfs/tests/common/src/java/com/android/fs/common/AuthFsTestRule.java
@@ -52,7 +52,7 @@
public static final String FUSE_SUPER_MAGIC_HEX = "65735546";
/** VM config entry path in the test APK */
- private static final String VM_CONFIG_PATH_IN_APK = "assets/vm_config.json";
+ private static final String VM_CONFIG_PATH_IN_APK = "assets/microdroid/vm_config.json";
/** Test directory on Android where data are located */
public static final String TEST_DIR = "/data/local/tmp/authfs";
diff --git a/javalib/api/test-current.txt b/javalib/api/test-current.txt
index 12c099d..34837a3 100644
--- a/javalib/api/test-current.txt
+++ b/javalib/api/test-current.txt
@@ -7,17 +7,20 @@
}
public final class VirtualMachineConfig {
+ method @FlaggedApi("RELEASE_AVF_ENABLE_VENDOR_MODULES") @NonNull public String getOs();
method @Nullable public String getPayloadConfigPath();
method public boolean isVmConsoleInputSupported();
}
public static final class VirtualMachineConfig.Builder {
+ method @FlaggedApi("RELEASE_AVF_ENABLE_VENDOR_MODULES") @NonNull public android.system.virtualmachine.VirtualMachineConfig.Builder setOs(@NonNull String);
method @NonNull @RequiresPermission(android.system.virtualmachine.VirtualMachine.USE_CUSTOM_VIRTUAL_MACHINE_PERMISSION) public android.system.virtualmachine.VirtualMachineConfig.Builder setPayloadConfigPath(@NonNull String);
method @FlaggedApi("RELEASE_AVF_ENABLE_VENDOR_MODULES") @NonNull @RequiresPermission(android.system.virtualmachine.VirtualMachine.USE_CUSTOM_VIRTUAL_MACHINE_PERMISSION) public android.system.virtualmachine.VirtualMachineConfig.Builder setVendorDiskImage(@NonNull java.io.File);
method @NonNull public android.system.virtualmachine.VirtualMachineConfig.Builder setVmConsoleInputSupported(boolean);
}
public class VirtualMachineManager {
+ method @FlaggedApi("RELEASE_AVF_ENABLE_VENDOR_MODULES") @NonNull public java.util.List<java.lang.String> getSupportedOSList() throws android.system.virtualmachine.VirtualMachineException;
method @RequiresPermission(android.system.virtualmachine.VirtualMachine.MANAGE_VIRTUAL_MACHINE_PERMISSION) public boolean isFeatureEnabled(String) throws android.system.virtualmachine.VirtualMachineException;
field public static final String FEATURE_DICE_CHANGES = "com.android.kvm.DICE_CHANGES";
field public static final String FEATURE_MULTI_TENANT = "com.android.kvm.MULTI_TENANT";
diff --git a/javalib/src/android/system/virtualmachine/VirtualMachineConfig.java b/javalib/src/android/system/virtualmachine/VirtualMachineConfig.java
index cc8f65b..cdc8f02 100644
--- a/javalib/src/android/system/virtualmachine/VirtualMachineConfig.java
+++ b/javalib/src/android/system/virtualmachine/VirtualMachineConfig.java
@@ -66,7 +66,7 @@
private static String[] EMPTY_STRING_ARRAY = {};
// These define the schema of the config file persisted on disk.
- private static final int VERSION = 6;
+ private static final int VERSION = 7;
private static final String KEY_VERSION = "version";
private static final String KEY_PACKAGENAME = "packageName";
private static final String KEY_APKPATH = "apkPath";
@@ -80,6 +80,7 @@
private static final String KEY_VM_OUTPUT_CAPTURED = "vmOutputCaptured";
private static final String KEY_VM_CONSOLE_INPUT_SUPPORTED = "vmConsoleInputSupported";
private static final String KEY_VENDOR_DISK_IMAGE_PATH = "vendorDiskImagePath";
+ private static final String KEY_OS = "os";
/** @hide */
@Retention(RetentionPolicy.SOURCE)
@@ -173,6 +174,8 @@
@Nullable private final File mVendorDiskImage;
+ private final String mOs;
+
private VirtualMachineConfig(
@Nullable String packageName,
@Nullable String apkPath,
@@ -185,7 +188,8 @@
long encryptedStorageBytes,
boolean vmOutputCaptured,
boolean vmConsoleInputSupported,
- @Nullable File vendorDiskImage) {
+ @Nullable File vendorDiskImage,
+ @NonNull String os) {
// This is only called from Builder.build(); the builder handles parameter validation.
mPackageName = packageName;
mApkPath = apkPath;
@@ -199,6 +203,7 @@
mVmOutputCaptured = vmOutputCaptured;
mVmConsoleInputSupported = vmConsoleInputSupported;
mVendorDiskImage = vendorDiskImage;
+ mOs = os;
}
/** Loads a config from a file. */
@@ -280,6 +285,11 @@
builder.setVendorDiskImage(new File(vendorDiskImagePath));
}
+ String os = b.getString(KEY_OS);
+ if (os != null) {
+ builder.setOs(os);
+ }
+
return builder.build();
}
@@ -318,6 +328,7 @@
if (mVendorDiskImage != null) {
b.putString(KEY_VENDOR_DISK_IMAGE_PATH, mVendorDiskImage.getAbsolutePath());
}
+ b.putString(KEY_OS, mOs);
b.writeToStream(output);
}
@@ -447,6 +458,19 @@
}
/**
+ * Returns the OS of the VM.
+ *
+ * @see Builder#setOs
+ * @hide
+ */
+ @TestApi
+ @FlaggedApi("RELEASE_AVF_ENABLE_VENDOR_MODULES")
+ @NonNull
+ public String getOs() {
+ return mOs;
+ }
+
+ /**
* Tests if this config is compatible with other config. Being compatible means that the configs
* can be interchangeably used for the same virtual machine; they do not change the VM identity
* or secrets. Such changes include varying the number of CPUs or the size of the RAM. Changes
@@ -469,7 +493,8 @@
&& Objects.equals(this.mPayloadConfigPath, other.mPayloadConfigPath)
&& Objects.equals(this.mPayloadBinaryName, other.mPayloadBinaryName)
&& Objects.equals(this.mPackageName, other.mPackageName)
- && Objects.equals(this.mApkPath, other.mApkPath);
+ && Objects.equals(this.mApkPath, other.mApkPath)
+ && Objects.equals(this.mOs, other.mOs);
}
/**
@@ -493,6 +518,7 @@
if (mPayloadBinaryName != null) {
VirtualMachinePayloadConfig payloadConfig = new VirtualMachinePayloadConfig();
payloadConfig.payloadBinaryName = mPayloadBinaryName;
+ payloadConfig.osName = mOs;
vsConfig.payload =
VirtualMachineAppConfig.Payload.payloadConfig(payloadConfig);
} else {
@@ -591,6 +617,8 @@
*/
@SystemApi
public static final class Builder {
+ private final String DEFAULT_OS = "microdroid";
+
@Nullable private final String mPackageName;
@Nullable private String mApkPath;
@Nullable private String mPayloadConfigPath;
@@ -604,6 +632,7 @@
private boolean mVmOutputCaptured = false;
private boolean mVmConsoleInputSupported = false;
@Nullable private File mVendorDiskImage;
+ private String mOs = DEFAULT_OS;
/**
* Creates a builder for the given context.
@@ -678,7 +707,8 @@
mEncryptedStorageBytes,
mVmOutputCaptured,
mVmConsoleInputSupported,
- mVendorDiskImage);
+ mVendorDiskImage,
+ mOs);
}
/**
@@ -910,5 +940,20 @@
mVendorDiskImage = vendorDiskImage;
return this;
}
+
+ /**
+ * Sets an OS for the VM. Defaults to {@code "microdroid"}.
+ *
+ * <p>See {@link VirtualMachineManager#getSupportedOSList} for available OS names.
+ *
+ * @hide
+ */
+ @TestApi
+ @FlaggedApi("RELEASE_AVF_ENABLE_VENDOR_MODULES")
+ @NonNull
+ public Builder setOs(@NonNull String os) {
+ mOs = requireNonNull(os, "os must not be null");
+ return this;
+ }
}
}
diff --git a/javalib/src/android/system/virtualmachine/VirtualMachineManager.java b/javalib/src/android/system/virtualmachine/VirtualMachineManager.java
index a4927db..2802659 100644
--- a/javalib/src/android/system/virtualmachine/VirtualMachineManager.java
+++ b/javalib/src/android/system/virtualmachine/VirtualMachineManager.java
@@ -18,6 +18,7 @@
import static java.util.Objects.requireNonNull;
+import android.annotation.FlaggedApi;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -39,6 +40,8 @@
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.ref.WeakReference;
+import java.util.Arrays;
+import java.util.List;
import java.util.Map;
/**
@@ -318,6 +321,25 @@
}
/**
+ * Returns a list of supported OS names.
+ *
+ * @hide
+ */
+ @TestApi
+ @FlaggedApi("RELEASE_AVF_ENABLE_VENDOR_MODULES")
+ @NonNull
+ public List<String> getSupportedOSList() throws VirtualMachineException {
+ synchronized (sCreateLock) {
+ VirtualizationService service = VirtualizationService.getInstance();
+ try {
+ return Arrays.asList(service.getBinder().getSupportedOSList());
+ } catch (RemoteException e) {
+ throw e.rethrowAsRuntimeException();
+ }
+ }
+ }
+
+ /**
* Returns {@code true} if given {@code featureName} is enabled.
*
* @hide
diff --git a/microdroid_manager/src/vm_secret.rs b/microdroid_manager/src/vm_secret.rs
index dea6af1..9b7d4f1 100644
--- a/microdroid_manager/src/vm_secret.rs
+++ b/microdroid_manager/src/vm_secret.rs
@@ -20,7 +20,7 @@
use secretkeeper_comm::data_types::request::Request;
use binder::{Strong};
use coset::CborSerializable;
-use dice_policy::{ConstraintSpec, ConstraintType, DicePolicy};
+use dice_policy::{ConstraintSpec, ConstraintType, DicePolicy, MissingAction};
use diced_open_dice::{DiceArtifacts, OwnedDiceArtifacts};
use keystore2_crypto::ZVec;
use openssl::hkdf::hkdf;
@@ -164,16 +164,12 @@
// TODO(b/291219197) : Add constraints on Extra apks as well!
fn sealing_policy(dice: &[u8]) -> Result<Vec<u8>, String> {
let constraint_spec = [
- ConstraintSpec::new(
- ConstraintType::ExactMatch,
- vec![AUTHORITY_HASH],
- /* Optional */ false,
- ),
- ConstraintSpec::new(ConstraintType::ExactMatch, vec![MODE], /* Optional */ false),
+ ConstraintSpec::new(ConstraintType::ExactMatch, vec![AUTHORITY_HASH], MissingAction::Fail),
+ ConstraintSpec::new(ConstraintType::ExactMatch, vec![MODE], MissingAction::Fail),
ConstraintSpec::new(
ConstraintType::GreaterOrEqual,
vec![CONFIG_DESC, SECURITY_VERSION],
- /* Optional */ true,
+ MissingAction::Ignore,
),
];
diff --git a/tests/benchmark/src/java/com/android/microdroid/benchmark/MicrodroidBenchmarks.java b/tests/benchmark/src/java/com/android/microdroid/benchmark/MicrodroidBenchmarks.java
index e31a55d..6314c25 100644
--- a/tests/benchmark/src/java/com/android/microdroid/benchmark/MicrodroidBenchmarks.java
+++ b/tests/benchmark/src/java/com/android/microdroid/benchmark/MicrodroidBenchmarks.java
@@ -119,7 +119,7 @@
public void setup() throws IOException {
grantPermission(VirtualMachine.MANAGE_VIRTUAL_MACHINE_PERMISSION);
grantPermission(VirtualMachine.USE_CUSTOM_VIRTUAL_MACHINE_PERMISSION);
- prepareTestSetup(mProtectedVm);
+ prepareTestSetup(mProtectedVm, null /* gki */);
setMaxPerformanceTaskProfile();
mInstrumentation = getInstrumentation();
}
diff --git a/tests/helper/src/java/com/android/microdroid/test/device/MicrodroidDeviceTestBase.java b/tests/helper/src/java/com/android/microdroid/test/device/MicrodroidDeviceTestBase.java
index 817bd85..c2244bc 100644
--- a/tests/helper/src/java/com/android/microdroid/test/device/MicrodroidDeviceTestBase.java
+++ b/tests/helper/src/java/com/android/microdroid/test/device/MicrodroidDeviceTestBase.java
@@ -48,7 +48,11 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
import java.util.OptionalLong;
+import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@@ -58,6 +62,9 @@
private static final String TAG = "MicrodroidDeviceTestBase";
private final String MAX_PERFORMANCE_TASK_PROFILE = "CPUSET_SP_TOP_APP";
+ protected static final Set<String> SUPPORTED_GKI_VERSIONS =
+ Collections.unmodifiableSet(new HashSet(Arrays.asList("android14-6.1")));
+
public static boolean isCuttlefish() {
return getDeviceProperties().isCuttlefish();
}
@@ -105,6 +112,7 @@
private Context mCtx;
private boolean mProtectedVm;
+ private String mOs;
protected Context getContext() {
return mCtx;
@@ -115,13 +123,17 @@
}
public VirtualMachineConfig.Builder newVmConfigBuilder() {
- return new VirtualMachineConfig.Builder(mCtx).setProtectedVm(mProtectedVm);
+ return new VirtualMachineConfig.Builder(mCtx).setProtectedVm(mProtectedVm).setOs(mOs);
}
protected final boolean isProtectedVm() {
return mProtectedVm;
}
+ protected final String os() {
+ return mOs;
+ }
+
/**
* Creates a new virtual machine, potentially removing an existing virtual machine with given
* name.
@@ -136,13 +148,14 @@
return vmm.create(name, config);
}
- public void prepareTestSetup(boolean protectedVm) {
+ public void prepareTestSetup(boolean protectedVm, String gki) {
mCtx = ApplicationProvider.getApplicationContext();
assume().withMessage("Device doesn't support AVF")
.that(mCtx.getPackageManager().hasSystemFeature(FEATURE_VIRTUALIZATION_FRAMEWORK))
.isTrue();
mProtectedVm = protectedVm;
+ mOs = gki != null ? "microdroid_gki-" + gki : "microdroid";
int capabilities = getVirtualMachineManager().getCapabilities();
if (protectedVm) {
@@ -154,6 +167,15 @@
.that(capabilities & VirtualMachineManager.CAPABILITY_NON_PROTECTED_VM)
.isNotEqualTo(0);
}
+
+ try {
+ assume().withMessage("Skip where requested OS \"" + mOs + "\" isn't supported")
+ .that(mOs)
+ .isIn(getVirtualMachineManager().getSupportedOSList());
+ } catch (VirtualMachineException e) {
+ Log.e(TAG, "Error getting supported OS list", e);
+ throw new RuntimeException("Failed to get supported OS list.", e);
+ }
}
public abstract static class VmEventListener implements VirtualMachineCallback {
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 be13196..848b43b 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
@@ -36,6 +36,7 @@
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Arrays;
+import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
@@ -55,7 +56,7 @@
/ MICRODROID_COMMAND_RETRY_INTERVAL_MILLIS);
protected static final Set<String> SUPPORTED_GKI_VERSIONS =
- new HashSet(Arrays.asList("android14-6.1"));
+ Collections.unmodifiableSet(new HashSet(Arrays.asList("android14-6.1")));
public static void prepareVirtualizationTestSetup(ITestDevice androidDevice)
throws DeviceNotAvailableException {
diff --git a/tests/hostside/java/com/android/microdroid/test/MicrodroidHostTests.java b/tests/hostside/java/com/android/microdroid/test/MicrodroidHostTests.java
index 1fa0976..21abdaa 100644
--- a/tests/hostside/java/com/android/microdroid/test/MicrodroidHostTests.java
+++ b/tests/hostside/java/com/android/microdroid/test/MicrodroidHostTests.java
@@ -90,7 +90,7 @@
private static final String SHELL_PACKAGE_NAME = "com.android.shell";
private static final String VIRT_APEX = "/apex/com.android.virt/";
- private static final int MIN_MEM_ARM64 = 145;
+ private static final int MIN_MEM_ARM64 = 160;
private static final int MIN_MEM_X86_64 = 196;
private static final int BOOT_COMPLETE_TIMEOUT = 30000; // 30 seconds
@@ -108,6 +108,7 @@
List<Object[]> ret = new ArrayList<>();
ret.add(new Object[] {true /* protectedVm */, null /* use microdroid kernel */});
ret.add(new Object[] {false /* protectedVm */, null /* use microdroid kernel */});
+ // TODO(b/302465542): run only the latest GKI on presubmit to reduce running time
for (String gki : SUPPORTED_GKI_VERSIONS) {
ret.add(new Object[] {true /* protectedVm */, gki});
ret.add(new Object[] {false /* protectedVm */, gki});
@@ -121,6 +122,8 @@
@Parameterized.Parameter(1)
public String mGki;
+ private String mOs;
+
@Rule public TestLogData mTestLogs = new TestLogData();
@Rule public TestName mTestName = new TestName();
@Rule public TestMetrics mMetrics = new TestMetrics();
@@ -149,7 +152,7 @@
throws Exception {
PayloadMetadata.write(
PayloadMetadata.metadata(
- "/mnt/apk/assets/vm_config.json",
+ "/mnt/apk/assets/" + mOs + "/vm_config.json",
PayloadMetadata.apk("microdroid-apk"),
apexes.stream()
.map(apex -> PayloadMetadata.apex(apex.name))
@@ -333,8 +336,7 @@
// - its idsig
// Load etc/microdroid.json
- String os = mGki != null ? "microdroid_gki-" + mGki : "microdroid";
- File microdroidConfigFile = new File(virtApexEtcDir, os + ".json");
+ File microdroidConfigFile = new File(virtApexEtcDir, mOs + ".json");
JSONObject config = new JSONObject(FileUtil.readStringFromFile(microdroidConfigFile));
// Replace paths so that the config uses re-signed images from TEST_ROOT
@@ -350,7 +352,7 @@
}
// Add partitions to the second disk
- final String initrdPath = TEST_ROOT + "etc/" + os + "_initrd_debuggable.img";
+ final String initrdPath = TEST_ROOT + "etc/" + mOs + "_initrd_debuggable.img";
config.put("initrd", initrdPath);
// Add instance image as a partition in disks[1]
disks.put(
@@ -409,7 +411,7 @@
public void protectedVmRunsPvmfw() throws Exception {
// Arrange
assumeProtectedVm();
- final String configPath = "assets/vm_config_apex.json";
+ final String configPath = "assets/" + mOs + "/vm_config_apex.json";
// Act
mMicrodroidDevice =
@@ -418,7 +420,6 @@
.memoryMib(minMemorySize())
.cpuTopology("match_host")
.protectedVm(true)
- .gki(mGki)
.build(getAndroidDevice());
// Assert
@@ -546,7 +547,6 @@
.memoryMib(minMemorySize())
.cpuTopology("match_host")
.protectedVm(protectedVm)
- .gki(mGki)
.build(getAndroidDevice());
mMicrodroidDevice.waitForBootComplete(BOOT_COMPLETE_TIMEOUT);
mMicrodroidDevice.enableAdbRoot();
@@ -567,7 +567,7 @@
assertThat(
isTombstoneGeneratedWithCmd(
mProtectedVm,
- "assets/vm_config.json",
+ "assets/" + mOs + "/vm_config.json",
"kill",
"-SIGSEGV",
"$(pidof microdroid_launcher)"))
@@ -581,7 +581,7 @@
assertThat(
isTombstoneGeneratedWithCmd(
mProtectedVm,
- "assets/vm_config_no_tombstone.json",
+ "assets/" + mOs + "/vm_config_no_tombstone.json",
"kill",
"-SIGSEGV",
"$(pidof microdroid_launcher)"))
@@ -595,7 +595,7 @@
assertThat(
isTombstoneGeneratedWithCmd(
mProtectedVm,
- "assets/vm_config.json",
+ "assets/" + mOs + "/vm_config.json",
"echo",
"c",
">",
@@ -659,7 +659,10 @@
private boolean isTombstoneGeneratedWithCrashConfig(boolean protectedVm, boolean debuggable)
throws Exception {
return isTombstoneGeneratedWithVmRunApp(
- protectedVm, debuggable, "--config-path", "assets/vm_config_crash.json");
+ protectedVm,
+ debuggable,
+ "--config-path",
+ "assets/" + mOs + "/vm_config_crash.json");
}
@Test
@@ -694,14 +697,13 @@
// Create VM with microdroid
TestDevice device = getAndroidDevice();
- final String configPath = "assets/vm_config_apex.json"; // path inside the APK
+ final String configPath = "assets/" + mOs + "/vm_config_apex.json"; // path inside the APK
ITestDevice microdroid =
MicrodroidBuilder.fromDevicePath(getPathForPackage(PACKAGE_NAME), configPath)
.debugLevel("full")
.memoryMib(minMemorySize())
.cpuTopology("match_host")
.protectedVm(mProtectedVm)
- .gki(mGki)
.build(device);
microdroid.waitForBootComplete(BOOT_COMPLETE_TIMEOUT);
device.shutdownMicrodroid(microdroid);
@@ -824,26 +826,24 @@
@Test
@CddTest(requirements = {"9.17/C-1-1", "9.17/C-1-2", "9.17/C/1-3"})
public void testMicrodroidBoots() throws Exception {
- final String configPath = "assets/vm_config.json"; // path inside the APK
+ final String configPath = "assets/" + mOs + "/vm_config.json"; // path inside the APK
testMicrodroidBootsWithBuilder(
MicrodroidBuilder.fromDevicePath(getPathForPackage(PACKAGE_NAME), configPath)
.debugLevel("full")
.memoryMib(minMemorySize())
.cpuTopology("match_host")
- .protectedVm(mProtectedVm)
- .gki(mGki));
+ .protectedVm(mProtectedVm));
}
@Test
public void testMicrodroidRamUsage() throws Exception {
- final String configPath = "assets/vm_config.json";
+ final String configPath = "assets/" + mOs + "/vm_config.json";
mMicrodroidDevice =
MicrodroidBuilder.fromDevicePath(getPathForPackage(PACKAGE_NAME), configPath)
.debugLevel("full")
.memoryMib(minMemorySize())
.cpuTopology("match_host")
.protectedVm(mProtectedVm)
- .gki(mGki)
.build(getAndroidDevice());
mMicrodroidDevice.waitForBootComplete(BOOT_COMPLETE_TIMEOUT);
mMicrodroidDevice.enableAdbRoot();
@@ -991,7 +991,7 @@
List<String> devices = getAssignableDevices();
assumeFalse("no assignable devices", devices.isEmpty());
- final String configPath = "assets/vm_config.json";
+ final String configPath = "assets/" + mOs + "/vm_config.json";
mMicrodroidDevice =
MicrodroidBuilder.fromDevicePath(getPathForPackage(PACKAGE_NAME), configPath)
.debugLevel("full")
@@ -999,7 +999,6 @@
.cpuTopology("match_host")
.protectedVm(true)
.addAssignableDevice(devices.get(0))
- .gki(mGki)
.build(getAndroidDevice());
mMicrodroidDevice.waitForBootComplete(BOOT_COMPLETE_TIMEOUT);
@@ -1034,6 +1033,8 @@
"GKI version \"" + mGki + "\" is not supported on this device",
getSupportedGKIVersions().contains(mGki));
}
+
+ mOs = (mGki != null) ? "microdroid_gki-" + mGki : "microdroid";
}
@After
@@ -1094,8 +1095,15 @@
return parseStringArrayFieldsFromVmInfo("Assignable devices: ");
}
+ private List<String> getSupportedOSList() throws Exception {
+ return parseStringArrayFieldsFromVmInfo("Available OS list: ");
+ }
+
private List<String> getSupportedGKIVersions() throws Exception {
- return parseStringArrayFieldsFromVmInfo("Available gki versions: ");
+ return getSupportedOSList().stream()
+ .filter(os -> os.startsWith("microdroid_gki-"))
+ .map(os -> os.replaceFirst("^microdroid_gki-", ""))
+ .collect(Collectors.toList());
}
private TestDevice getAndroidDevice() {
diff --git a/tests/pvmfw/java/com/android/pvmfw/test/DebugPolicyHostTests.java b/tests/pvmfw/java/com/android/pvmfw/test/DebugPolicyHostTests.java
index 7d0faa4..b84d7dc 100644
--- a/tests/pvmfw/java/com/android/pvmfw/test/DebugPolicyHostTests.java
+++ b/tests/pvmfw/java/com/android/pvmfw/test/DebugPolicyHostTests.java
@@ -57,7 +57,10 @@
@NonNull private static final String PACKAGE_NAME = "com.android.microdroid.test";
@NonNull private static final String MICRODROID_DEBUG_FULL = "full";
@NonNull private static final String MICRODROID_DEBUG_NONE = "none";
- @NonNull private static final String MICRODROID_CONFIG_PATH = "assets/vm_config_apex.json";
+
+ @NonNull
+ private static final String MICRODROID_CONFIG_PATH = "assets/microdroid/vm_config_apex.json";
+
@NonNull private static final String MICRODROID_LOG_PATH = TEST_ROOT + "log.txt";
private static final int BOOT_COMPLETE_TIMEOUT_MS = 30000; // 30 seconds
private static final int BOOT_FAILURE_WAIT_TIME_MS = 10000; // 10 seconds
diff --git a/tests/pvmfw/java/com/android/pvmfw/test/PvmfwImgTest.java b/tests/pvmfw/java/com/android/pvmfw/test/PvmfwImgTest.java
index 95c1c4e..9fbbd87 100644
--- a/tests/pvmfw/java/com/android/pvmfw/test/PvmfwImgTest.java
+++ b/tests/pvmfw/java/com/android/pvmfw/test/PvmfwImgTest.java
@@ -53,7 +53,10 @@
@NonNull private static final String PACKAGE_FILE_NAME = "MicrodroidTestApp.apk";
@NonNull private static final String PACKAGE_NAME = "com.android.microdroid.test";
@NonNull private static final String MICRODROID_DEBUG_FULL = "full";
- @NonNull private static final String MICRODROID_CONFIG_PATH = "assets/vm_config_apex.json";
+
+ @NonNull
+ private static final String MICRODROID_CONFIG_PATH = "assets/microdroid/vm_config_apex.json";
+
private static final int BOOT_COMPLETE_TIMEOUT_MS = 30000; // 30 seconds
private static final int BOOT_FAILURE_WAIT_TIME_MS = 10000; // 10 seconds
diff --git a/tests/testapk/assets/vm_config.json b/tests/testapk/assets/microdroid/vm_config.json
similarity index 100%
rename from tests/testapk/assets/vm_config.json
rename to tests/testapk/assets/microdroid/vm_config.json
diff --git a/tests/testapk/assets/vm_config_apex.json b/tests/testapk/assets/microdroid/vm_config_apex.json
similarity index 100%
rename from tests/testapk/assets/vm_config_apex.json
rename to tests/testapk/assets/microdroid/vm_config_apex.json
diff --git a/tests/testapk/assets/vm_config_crash.json b/tests/testapk/assets/microdroid/vm_config_crash.json
similarity index 100%
rename from tests/testapk/assets/vm_config_crash.json
rename to tests/testapk/assets/microdroid/vm_config_crash.json
diff --git a/tests/testapk/assets/vm_config_extra_apk.json b/tests/testapk/assets/microdroid/vm_config_extra_apk.json
similarity index 100%
rename from tests/testapk/assets/vm_config_extra_apk.json
rename to tests/testapk/assets/microdroid/vm_config_extra_apk.json
diff --git a/tests/testapk/assets/vm_config_no_task.json b/tests/testapk/assets/microdroid/vm_config_no_task.json
similarity index 100%
rename from tests/testapk/assets/vm_config_no_task.json
rename to tests/testapk/assets/microdroid/vm_config_no_task.json
diff --git a/tests/testapk/assets/vm_config_no_tombstone.json b/tests/testapk/assets/microdroid/vm_config_no_tombstone.json
similarity index 100%
rename from tests/testapk/assets/vm_config_no_tombstone.json
rename to tests/testapk/assets/microdroid/vm_config_no_tombstone.json
diff --git a/tests/testapk/assets/microdroid_gki-android14-6.1/vm_config.json b/tests/testapk/assets/microdroid_gki-android14-6.1/vm_config.json
new file mode 100644
index 0000000..2022127
--- /dev/null
+++ b/tests/testapk/assets/microdroid_gki-android14-6.1/vm_config.json
@@ -0,0 +1,10 @@
+{
+ "os": {
+ "name": "microdroid_gki-android14-6.1"
+ },
+ "task": {
+ "type": "microdroid_launcher",
+ "command": "MicrodroidTestNativeLib.so"
+ },
+ "export_tombstones": true
+}
diff --git a/tests/testapk/assets/microdroid_gki-android14-6.1/vm_config_apex.json b/tests/testapk/assets/microdroid_gki-android14-6.1/vm_config_apex.json
new file mode 100644
index 0000000..bd3998d
--- /dev/null
+++ b/tests/testapk/assets/microdroid_gki-android14-6.1/vm_config_apex.json
@@ -0,0 +1,21 @@
+{
+ "os": {
+ "name": "microdroid_gki-android14-6.1"
+ },
+ "task": {
+ "type": "microdroid_launcher",
+ "command": "MicrodroidTestNativeLib.so"
+ },
+ "apexes": [
+ {
+ "name": "com.android.art"
+ },
+ {
+ "name": "com.android.compos"
+ },
+ {
+ "name": "com.android.sdkext"
+ }
+ ],
+ "export_tombstones": true
+}
diff --git a/tests/testapk/assets/microdroid_gki-android14-6.1/vm_config_crash.json b/tests/testapk/assets/microdroid_gki-android14-6.1/vm_config_crash.json
new file mode 100644
index 0000000..4692258
--- /dev/null
+++ b/tests/testapk/assets/microdroid_gki-android14-6.1/vm_config_crash.json
@@ -0,0 +1,9 @@
+{
+ "os": {
+ "name": "microdroid_gki-android14-6.1"
+ },
+ "task": {
+ "type": "microdroid_launcher",
+ "command": "MicrodroidCrashNativeLib.so"
+ }
+}
diff --git a/tests/testapk/assets/microdroid_gki-android14-6.1/vm_config_extra_apk.json b/tests/testapk/assets/microdroid_gki-android14-6.1/vm_config_extra_apk.json
new file mode 100644
index 0000000..1602294
--- /dev/null
+++ b/tests/testapk/assets/microdroid_gki-android14-6.1/vm_config_extra_apk.json
@@ -0,0 +1,15 @@
+{
+ "os": {
+ "name": "microdroid_gki-android14-6.1"
+ },
+ "task": {
+ "type": "microdroid_launcher",
+ "command": "MicrodroidTestNativeLib.so"
+ },
+ "extra_apks": [
+ {
+ "path": "/system/etc/security/fsverity/BuildManifest.apk"
+ }
+ ],
+ "export_tombstones": true
+}
diff --git a/tests/testapk/assets/microdroid_gki-android14-6.1/vm_config_no_task.json b/tests/testapk/assets/microdroid_gki-android14-6.1/vm_config_no_task.json
new file mode 100644
index 0000000..8282f99
--- /dev/null
+++ b/tests/testapk/assets/microdroid_gki-android14-6.1/vm_config_no_task.json
@@ -0,0 +1,6 @@
+{
+ "os": {
+ "name": "microdroid_gki-android14-6.1"
+ },
+ "export_tombstones": true
+}
diff --git a/tests/testapk/assets/microdroid_gki-android14-6.1/vm_config_no_tombstone.json b/tests/testapk/assets/microdroid_gki-android14-6.1/vm_config_no_tombstone.json
new file mode 100644
index 0000000..6e8a136
--- /dev/null
+++ b/tests/testapk/assets/microdroid_gki-android14-6.1/vm_config_no_tombstone.json
@@ -0,0 +1,10 @@
+{
+ "os": {
+ "name": "microdroid_gki-android14-6.1"
+ },
+ "task": {
+ "type": "microdroid_launcher",
+ "command": "MicrodroidTestNativeLib.so"
+ },
+ "export_tombstones": false
+}
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 2367707..6605f89 100644
--- a/tests/testapk/src/java/com/android/microdroid/test/MicrodroidTests.java
+++ b/tests/testapk/src/java/com/android/microdroid/test/MicrodroidTests.java
@@ -31,8 +31,8 @@
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
-import static org.junit.Assume.assumeTrue;
import static org.junit.Assume.assumeFalse;
+import static org.junit.Assume.assumeTrue;
import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
@@ -96,7 +96,9 @@
import java.nio.file.Paths;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
+import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collection;
import java.util.List;
import java.util.OptionalLong;
import java.util.UUID;
@@ -118,17 +120,29 @@
private static final String KERNEL_VERSION = SystemProperties.get("ro.kernel.version");
- @Parameterized.Parameters(name = "protectedVm={0}")
- public static Object[] protectedVmConfigs() {
- return new Object[] { false, true };
+ @Parameterized.Parameters(name = "protectedVm={0},gki={1}")
+ public static Collection<Object[]> params() {
+ List<Object[]> ret = new ArrayList<>();
+ ret.add(new Object[] {true /* protectedVm */, null /* use microdroid kernel */});
+ ret.add(new Object[] {false /* protectedVm */, null /* use microdroid kernel */});
+ // TODO(b/302465542): run only the latest GKI on presubmit to reduce running time
+ for (String gki : SUPPORTED_GKI_VERSIONS) {
+ ret.add(new Object[] {true /* protectedVm */, gki});
+ ret.add(new Object[] {false /* protectedVm */, gki});
+ }
+ return ret;
}
- @Parameterized.Parameter public boolean mProtectedVm;
+ @Parameterized.Parameter(0)
+ public boolean mProtectedVm;
+
+ @Parameterized.Parameter(1)
+ public String mGki;
@Before
public void setup() {
grantPermission(VirtualMachine.MANAGE_VIRTUAL_MACHINE_PERMISSION);
- prepareTestSetup(mProtectedVm);
+ prepareTestSetup(mProtectedVm, mGki);
// USE_CUSTOM_VIRTUAL_MACHINE permission has protection level signature|development, meaning
// that it will be automatically granted when test apk is installed. We have some tests
// checking the behavior when caller doesn't have this permission (e.g.
@@ -146,7 +160,7 @@
private static final long ONE_MEBI = 1024 * 1024;
- private static final long MIN_MEM_ARM64 = 150 * ONE_MEBI;
+ private static final long MIN_MEM_ARM64 = 160 * ONE_MEBI;
private static final long MIN_MEM_X86_64 = 196 * ONE_MEBI;
private static final String EXAMPLE_STRING = "Literally any string!! :)";
@@ -473,8 +487,11 @@
@CddTest(requirements = {"9.17/C-1-1"})
public void vmConfigGetAndSetTests() {
// Minimal has as little as specified as possible; everything that can be is defaulted.
- VirtualMachineConfig.Builder minimalBuilder = newVmConfigBuilder();
- VirtualMachineConfig minimal = minimalBuilder.setPayloadBinaryName("binary.so").build();
+ VirtualMachineConfig.Builder minimalBuilder =
+ new VirtualMachineConfig.Builder(getContext())
+ .setPayloadBinaryName("binary.so")
+ .setProtectedVm(isProtectedVm());
+ VirtualMachineConfig minimal = minimalBuilder.build();
assertThat(minimal.getApkPath()).isNull();
assertThat(minimal.getDebugLevel()).isEqualTo(DEBUG_LEVEL_NONE);
@@ -486,6 +503,7 @@
assertThat(minimal.isEncryptedStorageEnabled()).isFalse();
assertThat(minimal.getEncryptedStorageBytes()).isEqualTo(0);
assertThat(minimal.isVmOutputCaptured()).isEqualTo(false);
+ assertThat(minimal.getOs()).isEqualTo("microdroid");
// Maximal has everything that can be set to some non-default value. (And has different
// values than minimal for the required fields.)
@@ -511,10 +529,16 @@
assertThat(maximal.isEncryptedStorageEnabled()).isTrue();
assertThat(maximal.getEncryptedStorageBytes()).isEqualTo(1_000_000);
assertThat(maximal.isVmOutputCaptured()).isEqualTo(true);
+ assertThat(maximal.getOs()).isEqualTo("microdroid");
assertThat(minimal.isCompatibleWith(maximal)).isFalse();
assertThat(minimal.isCompatibleWith(minimal)).isTrue();
assertThat(maximal.isCompatibleWith(maximal)).isTrue();
+
+ VirtualMachineConfig os = minimalBuilder.setOs("microdroid_gki-android14-6.1").build();
+ assertThat(os.getPayloadBinaryName()).isEqualTo("binary.so");
+ assertThat(os.getOs()).isEqualTo("microdroid_gki-android14-6.1");
+ assertThat(os.isCompatibleWith(minimal)).isFalse();
}
@Test
@@ -626,6 +650,11 @@
.setProtectedVm(isProtectedVm())
.setPayloadBinaryName("binary.so");
assertConfigCompatible(currentContextConfig, otherContextBuilder).isFalse();
+
+ VirtualMachineConfig microdroidOsConfig = newBaselineBuilder().setOs("microdroid").build();
+ VirtualMachineConfig.Builder otherOsBuilder =
+ newBaselineBuilder().setOs("microdroid_gki-android14-6.1");
+ assertConfigCompatible(microdroidOsConfig, otherOsBuilder).isFalse();
}
private VirtualMachineConfig.Builder newBaselineBuilder() {
@@ -772,7 +801,7 @@
VirtualMachineConfig config =
newVmConfigBuilder()
- .setPayloadConfigPath("assets/vm_config.json")
+ .setPayloadConfigPath("assets/" + os() + "/vm_config.json")
.setMemoryBytes(minMemoryRequired())
.build();
@@ -894,7 +923,7 @@
grantPermission(VirtualMachine.USE_CUSTOM_VIRTUAL_MACHINE_PERMISSION);
VirtualMachineConfig config =
newVmConfigBuilder()
- .setPayloadConfigPath("assets/vm_config_extra_apk.json")
+ .setPayloadConfigPath("assets/" + os() + "/vm_config_extra_apk.json")
.setMemoryBytes(minMemoryRequired())
.setDebugLevel(DEBUG_LEVEL_FULL)
.build();
@@ -1039,7 +1068,7 @@
grantPermission(VirtualMachine.USE_CUSTOM_VIRTUAL_MACHINE_PERMISSION);
VirtualMachineConfig normalConfig =
newVmConfigBuilder()
- .setPayloadConfigPath("assets/vm_config.json")
+ .setPayloadConfigPath("assets/" + os() + "/vm_config.json")
.setDebugLevel(DEBUG_LEVEL_FULL)
.build();
forceCreateNewVirtualMachine("test_vm_a", normalConfig);
@@ -1066,7 +1095,7 @@
grantPermission(VirtualMachine.USE_CUSTOM_VIRTUAL_MACHINE_PERMISSION);
VirtualMachineConfig normalConfig =
newVmConfigBuilder()
- .setPayloadConfigPath("assets/vm_config.json")
+ .setPayloadConfigPath("assets/" + os() + "/vm_config.json")
.setDebugLevel(DEBUG_LEVEL_FULL)
.build();
forceCreateNewVirtualMachine("test_vm", normalConfig);
@@ -1090,7 +1119,7 @@
grantPermission(VirtualMachine.USE_CUSTOM_VIRTUAL_MACHINE_PERMISSION);
VirtualMachineConfig normalConfig =
newVmConfigBuilder()
- .setPayloadConfigPath("assets/vm_config.json")
+ .setPayloadConfigPath("assets/" + os() + "/vm_config.json")
.setDebugLevel(DEBUG_LEVEL_FULL)
.build();
VirtualMachine vm = forceCreateNewVirtualMachine("bcc_vm", normalConfig);
@@ -1249,7 +1278,7 @@
grantPermission(VirtualMachine.USE_CUSTOM_VIRTUAL_MACHINE_PERMISSION);
VirtualMachineConfig normalConfig =
newVmConfigBuilder()
- .setPayloadConfigPath("assets/vm_config_no_task.json")
+ .setPayloadConfigPath("assets/" + os() + "/vm_config_no_task.json")
.setDebugLevel(DEBUG_LEVEL_FULL)
.build();
forceCreateNewVirtualMachine("test_vm_invalid_config", normalConfig);
@@ -1269,8 +1298,8 @@
BootResult bootResult = tryBootVm(TAG, "test_vm_invalid_binary_path");
assertThat(bootResult.payloadStarted).isFalse();
- assertThat(bootResult.deathReason).isEqualTo(
- VirtualMachineCallback.STOP_REASON_MICRODROID_UNKNOWN_RUNTIME_ERROR);
+ assertThat(bootResult.deathReason)
+ .isEqualTo(VirtualMachineCallback.STOP_REASON_MICRODROID_UNKNOWN_RUNTIME_ERROR);
}
// Checks whether microdroid_launcher started but payload failed. reason must be recorded in the
@@ -1346,7 +1375,7 @@
grantPermission(VirtualMachine.USE_CUSTOM_VIRTUAL_MACHINE_PERMISSION);
VirtualMachineConfig config =
newVmConfigBuilder()
- .setPayloadConfigPath("assets/vm_config.json")
+ .setPayloadConfigPath("assets/" + os() + "/vm_config.json")
.setDebugLevel(DEBUG_LEVEL_FULL)
.build();
String vmNameOrig = "test_vm_orig";
@@ -1744,6 +1773,7 @@
@Test
public void testConsoleInputSupported() throws Exception {
assumeSupportedDevice();
+ assumeTrue("Not supported on GKI kernels", mGki == null);
VirtualMachineConfig config =
newVmConfigBuilder()
diff --git a/virtualizationmanager/Android.bp b/virtualizationmanager/Android.bp
index 60c94fc..f58e999 100644
--- a/virtualizationmanager/Android.bp
+++ b/virtualizationmanager/Android.bp
@@ -38,6 +38,7 @@
"libclap",
"libcommand_fds",
"libdisk",
+ "libglob",
"libhex",
"libhypervisor_props",
"liblazy_static",
diff --git a/virtualizationmanager/src/aidl.rs b/virtualizationmanager/src/aidl.rs
index 12b8f88..2603e77 100644
--- a/virtualizationmanager/src/aidl.rs
+++ b/virtualizationmanager/src/aidl.rs
@@ -69,12 +69,12 @@
IntoBinderResult,
};
use disk::QcowFile;
+use glob::glob;
use lazy_static::lazy_static;
use libfdt::Fdt;
use log::{debug, error, info, warn};
use microdroid_payload_config::{OsConfig, Task, TaskType, VmPayloadConfig};
use nix::unistd::pipe;
-use regex::Regex;
use rpcbinder::RpcServer;
use rustutils::system_properties;
use semver::VersionReq;
@@ -83,6 +83,7 @@
use std::ffi::{CStr, CString};
use std::fs::{canonicalize, read_dir, remove_file, File, OpenOptions};
use std::io::{BufRead, BufReader, Error, ErrorKind, Write};
+use std::iter;
use std::num::{NonZeroU16, NonZeroU32};
use std::os::unix::io::{FromRawFd, IntoRawFd};
use std::os::unix::raw::pid_t;
@@ -126,8 +127,8 @@
pub static ref GLOBAL_SERVICE: Strong<dyn IVirtualizationServiceInternal> =
wait_for_interface(BINDER_SERVICE_IDENTIFIER)
.expect("Could not connect to VirtualizationServiceInternal");
- static ref MICRODROID_GKI_OS_NAME_PATTERN: Regex =
- Regex::new(r"^microdroid_gki-android\d+-\d+\.\d+$").expect("Failed to construct Regex");
+ static ref SUPPORTED_OS_NAMES: HashSet<String> =
+ get_supported_os_names().expect("Failed to get list of supported os names");
}
fn create_or_update_idsig_file(
@@ -289,6 +290,11 @@
GLOBAL_SERVICE.getAssignableDevices()
}
+ /// Get a list of supported OSes.
+ fn getSupportedOSList(&self) -> binder::Result<Vec<String>> {
+ Ok(Vec::from_iter(SUPPORTED_OS_NAMES.iter().cloned()))
+ }
+
/// Returns whether given feature is enabled
fn isFeatureEnabled(&self, feature: &str) -> binder::Result<bool> {
check_manage_access()?;
@@ -728,14 +734,32 @@
}
}
-fn is_valid_os(os_name: &str) -> bool {
- if os_name == MICRODROID_OS_NAME {
- true
- } else if cfg!(vendor_modules) && MICRODROID_GKI_OS_NAME_PATTERN.is_match(os_name) {
- PathBuf::from(format!("/apex/com.android.virt/etc/{}.json", os_name)).exists()
- } else {
- false
+fn extract_os_name_from_config_path(config: &Path) -> Option<String> {
+ if config.extension()?.to_str()? != "json" {
+ return None;
}
+
+ Some(config.with_extension("").file_name()?.to_str()?.to_owned())
+}
+
+fn extract_os_names_from_configs(config_glob_pattern: &str) -> Result<HashSet<String>> {
+ let configs = glob(config_glob_pattern)?.collect::<Result<Vec<_>, _>>()?;
+ let os_names =
+ configs.iter().filter_map(|x| extract_os_name_from_config_path(x)).collect::<HashSet<_>>();
+
+ Ok(os_names)
+}
+
+fn get_supported_os_names() -> Result<HashSet<String>> {
+ if !cfg!(vendor_modules) {
+ return Ok(iter::once(MICRODROID_OS_NAME.to_owned()).collect());
+ }
+
+ extract_os_names_from_configs("/apex/com.android.virt/etc/microdroid*.json")
+}
+
+fn is_valid_os(os_name: &str) -> bool {
+ SUPPORTED_OS_NAMES.contains(os_name)
}
fn load_app_config(
@@ -1593,6 +1617,72 @@
tmp_dir.close()?;
Ok(())
}
+
+ fn test_extract_os_name_from_config_path(
+ path: &Path,
+ expected_result: Option<&str>,
+ ) -> Result<()> {
+ let result = extract_os_name_from_config_path(path);
+ if result.as_deref() != expected_result {
+ bail!("Expected {:?} but was {:?}", expected_result, &result)
+ }
+ Ok(())
+ }
+
+ #[test]
+ fn test_extract_os_name_from_microdroid_config() -> Result<()> {
+ test_extract_os_name_from_config_path(
+ Path::new("/apex/com.android.virt/etc/microdroid.json"),
+ Some("microdroid"),
+ )
+ }
+
+ #[test]
+ fn test_extract_os_name_from_microdroid_gki_config() -> Result<()> {
+ test_extract_os_name_from_config_path(
+ Path::new("/apex/com.android.virt/etc/microdroid_gki-android14-6.1.json"),
+ Some("microdroid_gki-android14-6.1"),
+ )
+ }
+
+ #[test]
+ fn test_extract_os_name_from_invalid_path() -> Result<()> {
+ test_extract_os_name_from_config_path(
+ Path::new("/apex/com.android.virt/etc/microdroid.img"),
+ None,
+ )
+ }
+
+ #[test]
+ fn test_extract_os_name_from_configs() -> Result<()> {
+ let tmp_dir = tempfile::TempDir::new()?;
+ let tmp_dir_path = tmp_dir.path().to_owned();
+
+ let mut os_names: HashSet<String> = HashSet::new();
+ os_names.insert("microdroid".to_owned());
+ os_names.insert("microdroid_gki-android14-6.1".to_owned());
+ os_names.insert("microdroid_gki-android15-6.1".to_owned());
+
+ // config files
+ for os_name in &os_names {
+ std::fs::write(tmp_dir_path.join(os_name.to_owned() + ".json"), b"")?;
+ }
+
+ // fake files not related to configs
+ std::fs::write(tmp_dir_path.join("microdroid_super.img"), b"")?;
+ std::fs::write(tmp_dir_path.join("microdroid_foobar.apk"), b"")?;
+
+ let glob_pattern = match tmp_dir_path.join("microdroid*.json").to_str() {
+ Some(s) => s.to_owned(),
+ None => bail!("tmp_dir_path {:?} is not UTF-8", tmp_dir_path),
+ };
+
+ let result = extract_os_names_from_configs(&glob_pattern)?;
+ if result != os_names {
+ bail!("Expected {:?} but was {:?}", os_names, result);
+ }
+ Ok(())
+ }
}
struct SecretkeeperProxy(Strong<dyn ISecretkeeper>);
diff --git a/virtualizationservice/aidl/android/system/virtualizationservice/IVirtualizationService.aidl b/virtualizationservice/aidl/android/system/virtualizationservice/IVirtualizationService.aidl
index d6a1299..92a5812 100644
--- a/virtualizationservice/aidl/android/system/virtualizationservice/IVirtualizationService.aidl
+++ b/virtualizationservice/aidl/android/system/virtualizationservice/IVirtualizationService.aidl
@@ -66,6 +66,11 @@
*/
AssignableDevice[] getAssignableDevices();
+ /**
+ * Get a list of supported OSes.
+ */
+ String[] getSupportedOSList();
+
/** Returns whether given feature is enabled. */
boolean isFeatureEnabled(in String feature);
}
diff --git a/vm/src/main.rs b/vm/src/main.rs
index 9a92f13..5c07eed 100644
--- a/vm/src/main.rs
+++ b/vm/src/main.rs
@@ -27,7 +27,6 @@
use clap::{Args, Parser};
use create_idsig::command_create_idsig;
use create_partition::command_create_partition;
-use glob::glob;
use run::{command_run, command_run_app, command_run_microdroid};
use std::num::NonZeroU16;
use std::path::{Path, PathBuf};
@@ -316,12 +315,6 @@
Ok(())
}
-fn extract_gki_version(gki_config: &Path) -> Option<&str> {
- let name = gki_config.file_name()?;
- let name_str = name.to_str()?;
- name_str.strip_prefix("microdroid_gki-")?.strip_suffix(".json")
-}
-
/// Print information about supported VM types.
fn command_info() -> Result<(), Error> {
let non_protected_vm_supported = hypervisor_props::is_vm_supported()?;
@@ -361,11 +354,8 @@
let devices = devices.into_iter().map(|x| x.node).collect::<Vec<_>>();
println!("Assignable devices: {}", serde_json::to_string(&devices)?);
- let gki_configs =
- glob("/apex/com.android.virt/etc/microdroid_gki-*.json")?.collect::<Result<Vec<_>, _>>()?;
- let gki_versions =
- gki_configs.iter().filter_map(|x| extract_gki_version(x)).collect::<Vec<_>>();
- println!("Available gki versions: {}", serde_json::to_string(&gki_versions)?);
+ let os_list = get_service()?.getSupportedOSList()?;
+ println!("Available OS list: {}", serde_json::to_string(&os_list)?);
Ok(())
}