diff --git a/libs/framework-virtualization/Android.bp b/libs/framework-virtualization/Android.bp
new file mode 100644
index 0000000..d3a2b54
--- /dev/null
+++ b/libs/framework-virtualization/Android.bp
@@ -0,0 +1,55 @@
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+java_sdk_library {
+    name: "framework-virtualization",
+
+    defaults: ["non-updatable-framework-module-defaults"],
+
+    jarjar_rules: "jarjar-rules.txt",
+
+    srcs: ["src/**/*.java"],
+    static_libs: [
+        "android.system.virtualizationservice-java",
+        "avf_aconfig_flags_java",
+        // For android.sysprop.HypervisorProperties
+        "PlatformProperties",
+    ],
+
+    apex_available: ["com.android.virt"],
+
+    permitted_packages: [
+        "android.system.virtualmachine",
+        "android.system.virtualizationservice",
+        // android.sysprop.*, renamed by jarjar
+        "com.android.system.virtualmachine.sysprop",
+    ],
+    errorprone: {
+        enabled: true,
+        javacflags: [
+            // We use @GuardedBy and we want a test failure if our locking isn't consistent with it.
+            "-Xep:GuardedBy:ERROR",
+        ],
+    },
+
+    sdk_version: "core_platform",
+    stub_only_libs: [
+        "android_module_lib_stubs_current",
+    ],
+    impl_only_libs: [
+        "framework",
+    ],
+    impl_library_visibility: [
+        "//packages/modules/Virtualization:__subpackages__",
+    ],
+    aconfig_declarations: [
+        "avf_aconfig_flags",
+    ],
+    lint: {
+        baseline_filename: "lint-baseline.xml",
+        warning_checks: [
+            "FlaggedApi",
+        ],
+    },
+}
diff --git a/libs/framework-virtualization/README.md b/libs/framework-virtualization/README.md
new file mode 100644
index 0000000..0dd7e64
--- /dev/null
+++ b/libs/framework-virtualization/README.md
@@ -0,0 +1,377 @@
+# Android Virtualization Framework API
+
+These Java APIs allow an app to configure and run a Virtual Machine running
+[Microdroid](../build/microdroid/README.md) and execute native code from the app (the
+payload) within it.
+
+There is more information on AVF [here](../README.md). To see how to package the
+payload code that is to run inside a VM, and the native API available to it, see
+the [VM Payload API](../libs/libvm_payload/README.md)
+
+The API classes are all in the
+[`android.system.virtualmachine`](src/android/system/virtualmachine) package.
+
+All of these APIs were introduced in API level 34 (Android 14). The classes may
+not exist in devices running an earlier version.
+
+Note that they are all `@SystemApi` and require the restricted
+`android.permission.MANAGE_VIRTUAL_MACHINE` permission, so they are not
+available to third party apps. In Android 14 the permission was available only to
+privileged apps; in Android 15 it is available to all preinstalled apps. On both
+versions it can also be granted to other apps via `adb shell pm grant` for
+development purposes.
+
+
+## Detecting AVF Support
+
+The simplest way to detect whether a device has support for AVF is to retrieve
+an instance of the
+[`VirtualMachineManager`](src/android/system/virtualmachine/VirtualMachineManager.java)
+class; if the result is not `null` then the device has support. You can then
+find out whether protected, non-protected VMs, or both are supported using the
+`getCapabilities()` method. Note that this code requires API level 34 or higher:
+
+```Java
+VirtualMachineManager vmm = context.getSystemService(VirtualMachineManager.class);
+if (vmm == null) {
+    // AVF is not supported.
+} else {
+    // AVF is supported.
+    int capabilities = vmm.getCapabilities();
+    if ((capabilties & CAPABILITY_PROTECTED_VM) != 0) {
+        // Protected VMs supported.
+    }
+    if ((capabilties & CAPABILITY_NON_PROTECTED_VM) != 0) {
+        // Non-Protected VMs supported.
+    }
+}
+```
+
+An alternative for detecting AVF support is to query support for the
+`android.software.virtualization_framework` system feature. This method will
+work on any API level, and return false if it is below 34:
+
+```Java
+if (getPackageManager().hasSystemFeature(PackageManager.FEATURE_VIRTUALIZATION_FRAMEWORK)) {
+    // AVF is supported.
+}
+```
+
+You can also express a dependency on this system feature in your app's manifest
+with a
+[`<uses-feature>`](https://developer.android.com/guide/topics/manifest/uses-feature-element)
+element.
+
+
+## Starting a VM
+
+Once you have an instance of the
+[`VirtualMachineManager`](src/android/system/virtualmachine/VirtualMachineManager.java),
+a VM can be started by:
+- Specifying the desired VM configuration, using a
+  [`VirtualMachineConfig`](src/android/system/virtualmachine/VirtualMachineConfig.java)
+  builder;
+- Creating a new
+  [`VirtualMachine`](src/android/system/virtualmachine/VirtualMachine.java)
+  instance (or retrieving an existing one);
+- Registering to retrieve events from the VM by providing a
+  [`VirtualMachineCallback`](src/android/system/virtualmachine/VirtualMachineCallback.java)
+  (optional, but recommended);
+- Running the VM.
+
+A minimal example might look like this:
+
+```Java
+VirtualMachineConfig config =
+        new VirtualMachineConfig.Builder(this)
+            .setProtectedVm(true)
+            .setPayloadBinaryName("my_payload.so")
+            .build();
+
+VirtualMachine vm = vmm.getOrCreate("my vm", config);
+
+vm.setCallback(executor, new VirtualMachineCallback() {...});
+
+vm.run();
+```
+
+Here we are running a protected VM, which will execute the code in the
+`my_payload.so` file included in your APK.
+
+Information about the VM, including its configuration, is stored in files in
+your app's private data directory. The file names are based on the VM name you
+supply. So once an instance of a VM has been created it can be retrieved by name
+even if the app is restarted or the device is rebooted. Directly inspecting or
+modifying these files is not recommended.
+
+The `getOrCreate()` call will retrieve an existing VM instance if it exists (in
+which case the `config` parameter is ignored), or create a new one
+otherwise. There are also separate `get()` and `create()` methods.
+
+The `run()` method is asynchronous; it returns successfully once the VM is
+starting. You can find out when the VM is ready, or if it fails, via your
+`VirtualMachineCallback` implementation.
+
+## VM Configuration
+
+There are other things that you can specify as part of the
+[`VirtualMachineConfig`](src/android/system/virtualmachine/VirtualMachineConfig.java):
+- Whether the VM should be debuggable. A debuggable VM is not secure, but it
+  does allow access to logs from inside the VM, which can be useful for
+  troubleshooting.
+- How much memory should be available to the VM. (This is an upper bound;
+  typically memory is allocated to the VM as it is needed until the limit is
+  reached - but there is some overhead proportional to the maximum size.)
+- How many virtual CPUs the VM has.
+- How much encrypted storage the VM has.
+- The path to the installed APK containing the code to run as the VM
+  payload. (Normally you don't need this; the APK path is determined from the
+  context passed to the config builder.)
+
+## VM Life-cycle
+
+To find out the progress of the Virtual Machine once it is started you should
+implement the methods defined by
+[`VirtualMachineCallback`](src/android/system/virtualmachine/VirtualMachineCallback.java). These
+are called when the following events happen:
+- `onPayloadStarted()`: The VM payload is about to be run.
+- `onPayloadReady()`: The VM payload is running and ready to accept
+  connections. (This notification is triggered by the payload code, using the
+  [`AVmPayload_notifyPayloadReady()`](../libs/libvm_payload/include/vm_payload.h)
+  function.)
+- `onPayloadFinished()`: The VM payload has exited normally. The exit code of
+  the VM (the value returned by [`AVmPayload_main()`](../libs/libvm_payload/README.md))
+  is supplied as a parameter.
+- `onError()`: The VM failed; something went wrong. An error code and
+  human-readable message are provided which may help diagnosing the problem.
+- `onStopped()`: The VM is no longer running. This is the final notification
+  from any VM run, whether or not it was successful. You can run the VM again
+  when you want to. A reason code indicating why the VM stopped is supplied as a
+  parameter.
+
+You can also query the status of a VM at any point by calling `getStatus()` on
+the `VirtualMachine` object. This will return one of the following values:
+- `STATUS_STOPPED`: The VM is not running - either it has not yet been started,
+  or it stopped after running.
+- `STATUS_RUNNING`: The VM is running. Your payload inside the VM may not be
+  running, since the VM may be in the process of starting or stopping.
+- `STATUS_DELETED`: The VM has been deleted, e.g. by calling the `delete()`
+  method on
+  [`VirtualMachineManager`](src/android/system/virtualmachine/VirtualMachineManager.java). This
+  is irreversible - once a VM is in this state it will never leave it.
+
+Some methods on
+[`VirtualMachine`](src/android/system/virtualmachine/VirtualMachine.java) can
+only be called when the VM status is `STATUS_RUNNING` (e.g. `stop()`), and some
+can only be called when the it is `STATUS_STOPPED` (e.g. `run()`).
+
+## VM Identity and Secrets
+
+Every VM has a 32-byte secret unique to it, which is not available to the
+host. We refer to this as the VM identity.  The secret, and thus the identity,
+doesn’t normally change if the same VM is stopped and started, even after a
+reboot.
+
+In Android 14 the secret is derived, using the [Open Profile for
+DICE](https://pigweed.googlesource.com/open-dice/+/refs/heads/main/docs/android.md),
+from:
+- A device-specific randomly generated value;
+- The complete system image;
+- A per-instance salt;
+- The code running in the VM, including the bootloader, kernel, Microdroid and
+  payload;
+- Significant VM configuration options, e.g.  whether the VM is debuggable.
+
+Any change to any of these will mean a different secret is generated.  So while
+an attacker could start a similar VM with maliciously altered code, that VM will
+not have access to the same secret. An attempt to start an existing VM instance
+which doesn't derive the same secret will fail.
+
+However, this also means that if the payload code changes - for example, your
+app is updated - then this also changes the identity. An existing VM instance
+will no longer be runnable, and you will have to delete it and create a new
+instance with a new secret.
+
+The payload code is not given direct access to the VM secret, but an API is
+provided to allow deterministically deriving further secrets from it,
+e.g. encryption or signing keys. See
+[`AVmPayload_getVmInstanceSecret()`](../libs/libvm_payload/include/vm_payload.h).
+
+Some VM configuration changes are allowed that don’t affect the identity -
+e.g. changing the number of CPUs or the amount of memory allocated to the
+VM. This can be done using the `setConfig()` method on
+[`VirtualMachine`](src/android/system/virtualmachine/VirtualMachine.java).
+
+Deleting a VM (using the `delete()` method on
+[`VirtualMachineManager`](src/android/system/virtualmachine/VirtualMachineManager.java))
+and recreating it will generate a new salt, so the new VM will have a different
+secret, even if it is otherwise identical.
+
+## Communicating with a VM
+
+Once the VM payload has successfully started you will probably want to establish
+communication between it and your app.
+
+Only the app that started a VM can connect to it. The VM can accept connections
+from the app, but cannot initiate connections to other VMs or other processes in
+the host Android.
+
+### Vsock
+
+The simplest form of communication is using a socket running over the
+[vsock](https://man7.org/linux/man-pages/man7/vsock.7.html) protocol.
+
+We suggest that the VM payload should create a listening socket (using the
+standard socket API) and then trigger the `onPayloadReady()` callback; the app
+can then connect to the socket. This helps to avoid a race condition where the
+app tries to connect before the VM is listening, necessitating a retry
+mechanism.
+
+In the payload this might look like this:
+
+```C++
+#include "vm_payload.h"
+
+extern "C" int AVmPayload_main() {
+  int fd = socket(AF_VSOCK, SOCK_STREAM, 0);
+  // bind, listen
+  AVmPayload_notifyPayloadReady();
+  // accept, read/write, ...
+}
+```
+
+And, in the app, like this:
+
+```Java
+void onPayloadReady(VirtualMachine vm) {
+  ParcelFileDescriptor pfd = vm.connectVsock(port);
+  // ...
+}
+```
+
+Vsock is useful for simple communication, or transferring of bulk data. For a
+richer RPC style of communication we suggest using Binder.
+
+### Binder
+
+The use of AIDL interfaces between the VM and app is supported via Binder RPC,
+which transmits messages over an underlying vsock socket.
+
+Note that Binder RPC has some limitations compared to the kernel Binder used in
+Android - for example file descriptors can't be sent. It also isn't possible to
+send a kernel Binder interface over Binder RPC, or vice versa.
+
+There is a payload API to allow an AIDL interface to be served over a specific
+vsock port, and the VirtualMachine class provides a way to connect to the VM and
+retrieve an instance of the interface.
+
+The payload code to serve a hypothetical `IPayload` interface might look like
+this:
+
+```C++
+class PayloadImpl : public BnPayload { ... };
+
+
+extern "C" int AVmPayload_main() {
+  auto service = ndk::SharedRefBase::make<PayloadImpl>();
+  auto callback = [](void*) {
+    AVmPayload_notifyPayloadReady();
+  };
+  AVmPayload_runVsockRpcServer(service->asBinder().get(),
+    port, callback, nullptr);
+}
+
+```
+
+And then the app code to connect to it could look like this:
+
+```Java
+void onPayloadReady(VirtualMachine vm) {
+  IPayload payload =
+    Payload.Stub.asInterface(vm.connectToVsockServer(port));
+  // ...
+}
+```
+
+## Stopping a VM
+
+You can stop a VM abruptly by calling the `stop()` method on the
+[`VirtualMachine`](src/android/system/virtualmachine/VirtualMachine.java)
+instance. This is equivalent to turning off the power; the VM gets no
+opportunity to clean up at all. Any unwritten data might be lost.
+
+A better strategy might be to wait for the VM to exit cleanly (e.g. waiting for
+the `onStopped()` callback).
+
+Then you can arrange for your VM payload code to exit when it has finished its
+task (by returning from [`AVmPayload_main()`](../libs/libvm_payload/README.md), or
+calling `exit()`). Alternatively you could exit when you receive a request to do
+so from the app, e.g. via binder.
+
+When the VM payload does this you will receive an `onPayloadFinished()`
+callback, if you have installed a
+[`VirtualMachineCallback`](src/android/system/virtualmachine/VirtualMachineCallback.java),
+which includes the payload's exit code.
+
+Use of `stop()` should be reserved as a recovery mechanism - for example if the
+VM has not stopped within a reasonable time (a few seconds, say) after being
+requested to.
+
+The status of a VM will be `STATUS_STOPPED` if your `onStopped()` callback is
+invoked, or after a successful call to `stop()`. Note that your `onStopped()`
+will be called on the VM even if it ended as a result of a call to `stop()`.
+
+# Encrypted Storage
+
+When configuring a VM you can specify that it should have access to an encrypted
+storage filesystem of up to a specified size, using the
+`setEncryptedStorageBytes()` method on a
+[`VirtualMachineConfig`](src/android/system/virtualmachine/VirtualMachineConfig.java)
+builder.
+
+Inside the VM this storage is mounted at a path that can be retrieved via the
+[`AVmPayload_getEncryptedStoragePath()`](../libs/libvm_payload/include/vm_payload.h)
+function. The VM can create sub-directories and read and write files here. Any
+data written is persisted and should be available next time the VM is run. (An
+automatic sync is done when the payload exits normally.)
+
+Outside the VM the storage is persisted as a file in the app’s private data
+directory. The data is encrypted using a key derived from the VM secret, which
+is not made available outside the VM.
+
+So an attacker should not be able to decrypt the data; however, a sufficiently
+powerful attacker could delete it, wholly or partially roll it back to an
+earlier version, or modify it, corrupting the data.
+
+For more info see [README](https://cs.android.com/android/platform/superproject/main/+/main:packages/modules/Virtualization/libs/framework-virtualization/README.md)
+
+# Transferring a VM
+
+It is possible to make a copy of a VM instance. This can be used to transfer a
+VM from one app to another, which can be useful in some circumstances.
+
+This should only be done while the VM is stopped. The first step is to call
+`toDescriptor()` on the
+[`VirtualMachine`](src/android/system/virtualmachine/VirtualMachine.java)
+instance, which returns a
+[`VirtualMachineDescriptor`](src/android/system/virtualmachine/VirtualMachineDescriptor.java)
+object. This object internally contains open file descriptors to the files that
+hold the VM's state (its instance data, configuration, and encrypted storage).
+
+A `VirtualMachineDescriptor` is
+[`Parcelable`](https://developer.android.com/reference/android/os/Parcelable),
+so it can be passed to another app via a Binder call.  Any app with a
+`VirtualMachineDescriptor` can pass it, along with a new VM name, to the
+`importFromDescriptor()` method on
+[`VirtualMachineManager`](src/android/system/virtualmachine/VirtualMachineManager.java). This
+is equivalent to calling `create()` with the same name and configuration, except
+that the new VM is the same instance as the original, with the same VM secret,
+and has access to a copy of the original's encrypted storage.
+
+Once the transfer has been completed it would be reasonable to delete the
+original VM, using the `delete()` method on `VirtualMachineManager`.
+
+
+
+
+
diff --git a/libs/framework-virtualization/api/current.txt b/libs/framework-virtualization/api/current.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/libs/framework-virtualization/api/current.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/libs/framework-virtualization/api/module-lib-current.txt b/libs/framework-virtualization/api/module-lib-current.txt
new file mode 100644
index 0000000..4d59764
--- /dev/null
+++ b/libs/framework-virtualization/api/module-lib-current.txt
@@ -0,0 +1,9 @@
+// Signature format: 2.0
+package android.system.virtualmachine {
+
+  public class VirtualizationFrameworkInitializer {
+    method public static void registerServiceWrappers();
+  }
+
+}
+
diff --git a/libs/framework-virtualization/api/module-lib-removed.txt b/libs/framework-virtualization/api/module-lib-removed.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/libs/framework-virtualization/api/module-lib-removed.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/libs/framework-virtualization/api/removed.txt b/libs/framework-virtualization/api/removed.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/libs/framework-virtualization/api/removed.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/libs/framework-virtualization/api/system-current.txt b/libs/framework-virtualization/api/system-current.txt
new file mode 100644
index 0000000..d9bafa1
--- /dev/null
+++ b/libs/framework-virtualization/api/system-current.txt
@@ -0,0 +1,110 @@
+// Signature format: 2.0
+package android.system.virtualmachine {
+
+  public class VirtualMachine implements java.lang.AutoCloseable {
+    method public void clearCallback();
+    method @WorkerThread public void close();
+    method @NonNull @WorkerThread public android.os.IBinder connectToVsockServer(@IntRange(from=android.system.virtualmachine.VirtualMachine.MIN_VSOCK_PORT, to=android.system.virtualmachine.VirtualMachine.MAX_VSOCK_PORT) long) throws android.system.virtualmachine.VirtualMachineException;
+    method @NonNull @WorkerThread public android.os.ParcelFileDescriptor connectVsock(@IntRange(from=android.system.virtualmachine.VirtualMachine.MIN_VSOCK_PORT, to=android.system.virtualmachine.VirtualMachine.MAX_VSOCK_PORT) long) throws android.system.virtualmachine.VirtualMachineException;
+    method @NonNull @WorkerThread public android.system.virtualmachine.VirtualMachineConfig getConfig();
+    method @NonNull @WorkerThread public java.io.InputStream getConsoleOutput() throws android.system.virtualmachine.VirtualMachineException;
+    method @NonNull @WorkerThread public java.io.InputStream getLogOutput() throws android.system.virtualmachine.VirtualMachineException;
+    method @NonNull public String getName();
+    method @WorkerThread public int getStatus();
+    method @RequiresPermission(android.system.virtualmachine.VirtualMachine.MANAGE_VIRTUAL_MACHINE_PERMISSION) @WorkerThread public void run() throws android.system.virtualmachine.VirtualMachineException;
+    method public void setCallback(@NonNull java.util.concurrent.Executor, @NonNull android.system.virtualmachine.VirtualMachineCallback);
+    method @NonNull @WorkerThread public android.system.virtualmachine.VirtualMachineConfig setConfig(@NonNull android.system.virtualmachine.VirtualMachineConfig) throws android.system.virtualmachine.VirtualMachineException;
+    method @WorkerThread public void stop() throws android.system.virtualmachine.VirtualMachineException;
+    method @NonNull @WorkerThread public android.system.virtualmachine.VirtualMachineDescriptor toDescriptor() throws android.system.virtualmachine.VirtualMachineException;
+    field public static final String MANAGE_VIRTUAL_MACHINE_PERMISSION = "android.permission.MANAGE_VIRTUAL_MACHINE";
+    field public static final long MAX_VSOCK_PORT = 4294967295L; // 0xffffffffL
+    field public static final long MIN_VSOCK_PORT = 1024L; // 0x400L
+    field public static final int STATUS_DELETED = 2; // 0x2
+    field public static final int STATUS_RUNNING = 1; // 0x1
+    field public static final int STATUS_STOPPED = 0; // 0x0
+    field public static final String USE_CUSTOM_VIRTUAL_MACHINE_PERMISSION = "android.permission.USE_CUSTOM_VIRTUAL_MACHINE";
+  }
+
+  public interface VirtualMachineCallback {
+    method public void onError(@NonNull android.system.virtualmachine.VirtualMachine, int, @NonNull String);
+    method public void onPayloadFinished(@NonNull android.system.virtualmachine.VirtualMachine, int);
+    method public void onPayloadReady(@NonNull android.system.virtualmachine.VirtualMachine);
+    method public void onPayloadStarted(@NonNull android.system.virtualmachine.VirtualMachine);
+    method public void onStopped(@NonNull android.system.virtualmachine.VirtualMachine, int);
+    field public static final int ERROR_PAYLOAD_CHANGED = 2; // 0x2
+    field public static final int ERROR_PAYLOAD_INVALID_CONFIG = 3; // 0x3
+    field public static final int ERROR_PAYLOAD_VERIFICATION_FAILED = 1; // 0x1
+    field public static final int ERROR_UNKNOWN = 0; // 0x0
+    field public static final int STOP_REASON_BOOTLOADER_INSTANCE_IMAGE_CHANGED = 10; // 0xa
+    field public static final int STOP_REASON_BOOTLOADER_PUBLIC_KEY_MISMATCH = 9; // 0x9
+    field public static final int STOP_REASON_CRASH = 6; // 0x6
+    field public static final int STOP_REASON_HANGUP = 16; // 0x10
+    field public static final int STOP_REASON_INFRASTRUCTURE_ERROR = 0; // 0x0
+    field public static final int STOP_REASON_KILLED = 1; // 0x1
+    field public static final int STOP_REASON_MICRODROID_FAILED_TO_CONNECT_TO_VIRTUALIZATION_SERVICE = 11; // 0xb
+    field public static final int STOP_REASON_MICRODROID_INVALID_PAYLOAD_CONFIG = 14; // 0xe
+    field public static final int STOP_REASON_MICRODROID_PAYLOAD_HAS_CHANGED = 12; // 0xc
+    field public static final int STOP_REASON_MICRODROID_PAYLOAD_VERIFICATION_FAILED = 13; // 0xd
+    field public static final int STOP_REASON_MICRODROID_UNKNOWN_RUNTIME_ERROR = 15; // 0xf
+    field public static final int STOP_REASON_PVM_FIRMWARE_INSTANCE_IMAGE_CHANGED = 8; // 0x8
+    field public static final int STOP_REASON_PVM_FIRMWARE_PUBLIC_KEY_MISMATCH = 7; // 0x7
+    field public static final int STOP_REASON_REBOOT = 5; // 0x5
+    field public static final int STOP_REASON_SHUTDOWN = 3; // 0x3
+    field public static final int STOP_REASON_START_FAILED = 4; // 0x4
+    field public static final int STOP_REASON_UNKNOWN = 2; // 0x2
+    field public static final int STOP_REASON_VIRTUALIZATION_SERVICE_DIED = -1; // 0xffffffff
+  }
+
+  public final class VirtualMachineConfig {
+    method @Nullable public String getApkPath();
+    method public int getCpuTopology();
+    method public int getDebugLevel();
+    method @IntRange(from=0) public long getEncryptedStorageBytes();
+    method @IntRange(from=0) public long getMemoryBytes();
+    method @Nullable public String getPayloadBinaryName();
+    method public boolean isCompatibleWith(@NonNull android.system.virtualmachine.VirtualMachineConfig);
+    method public boolean isEncryptedStorageEnabled();
+    method public boolean isProtectedVm();
+    method public boolean isVmOutputCaptured();
+    field public static final int CPU_TOPOLOGY_MATCH_HOST = 1; // 0x1
+    field public static final int CPU_TOPOLOGY_ONE_CPU = 0; // 0x0
+    field public static final int DEBUG_LEVEL_FULL = 1; // 0x1
+    field public static final int DEBUG_LEVEL_NONE = 0; // 0x0
+  }
+
+  public static final class VirtualMachineConfig.Builder {
+    ctor public VirtualMachineConfig.Builder(@NonNull android.content.Context);
+    method @NonNull public android.system.virtualmachine.VirtualMachineConfig build();
+    method @NonNull public android.system.virtualmachine.VirtualMachineConfig.Builder setApkPath(@NonNull String);
+    method @NonNull public android.system.virtualmachine.VirtualMachineConfig.Builder setCpuTopology(int);
+    method @NonNull public android.system.virtualmachine.VirtualMachineConfig.Builder setDebugLevel(int);
+    method @NonNull public android.system.virtualmachine.VirtualMachineConfig.Builder setEncryptedStorageBytes(@IntRange(from=1) long);
+    method @NonNull public android.system.virtualmachine.VirtualMachineConfig.Builder setMemoryBytes(@IntRange(from=1) long);
+    method @NonNull public android.system.virtualmachine.VirtualMachineConfig.Builder setPayloadBinaryName(@NonNull String);
+    method @NonNull public android.system.virtualmachine.VirtualMachineConfig.Builder setProtectedVm(boolean);
+    method @NonNull public android.system.virtualmachine.VirtualMachineConfig.Builder setVmOutputCaptured(boolean);
+  }
+
+  public final class VirtualMachineDescriptor implements java.lang.AutoCloseable android.os.Parcelable {
+    method public void close();
+    method public int describeContents();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.system.virtualmachine.VirtualMachineDescriptor> CREATOR;
+  }
+
+  public class VirtualMachineException extends java.lang.Exception {
+  }
+
+  public class VirtualMachineManager {
+    method @NonNull @RequiresPermission(android.system.virtualmachine.VirtualMachine.MANAGE_VIRTUAL_MACHINE_PERMISSION) @WorkerThread public android.system.virtualmachine.VirtualMachine create(@NonNull String, @NonNull android.system.virtualmachine.VirtualMachineConfig) throws android.system.virtualmachine.VirtualMachineException;
+    method @WorkerThread public void delete(@NonNull String) throws android.system.virtualmachine.VirtualMachineException;
+    method @Nullable @WorkerThread public android.system.virtualmachine.VirtualMachine get(@NonNull String) throws android.system.virtualmachine.VirtualMachineException;
+    method public int getCapabilities();
+    method @NonNull @WorkerThread public android.system.virtualmachine.VirtualMachine getOrCreate(@NonNull String, @NonNull android.system.virtualmachine.VirtualMachineConfig) throws android.system.virtualmachine.VirtualMachineException;
+    method @NonNull @WorkerThread public android.system.virtualmachine.VirtualMachine importFromDescriptor(@NonNull String, @NonNull android.system.virtualmachine.VirtualMachineDescriptor) throws android.system.virtualmachine.VirtualMachineException;
+    field public static final int CAPABILITY_NON_PROTECTED_VM = 2; // 0x2
+    field public static final int CAPABILITY_PROTECTED_VM = 1; // 0x1
+  }
+
+}
+
diff --git a/libs/framework-virtualization/api/system-removed.txt b/libs/framework-virtualization/api/system-removed.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/libs/framework-virtualization/api/system-removed.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/libs/framework-virtualization/api/test-current.txt b/libs/framework-virtualization/api/test-current.txt
new file mode 100644
index 0000000..7e8da26
--- /dev/null
+++ b/libs/framework-virtualization/api/test-current.txt
@@ -0,0 +1,40 @@
+// Signature format: 2.0
+package android.system.virtualmachine {
+
+  public class VirtualMachine implements java.lang.AutoCloseable {
+    method @FlaggedApi("com.android.system.virtualmachine.flags.avf_v_test_apis") @RequiresPermission(android.system.virtualmachine.VirtualMachine.USE_CUSTOM_VIRTUAL_MACHINE_PERMISSION) public void enableTestAttestation() throws android.system.virtualmachine.VirtualMachineException;
+    method @NonNull @WorkerThread public java.io.OutputStream getConsoleInput() throws android.system.virtualmachine.VirtualMachineException;
+    method @NonNull public java.io.File getRootDir();
+  }
+
+  public final class VirtualMachineConfig {
+    method @FlaggedApi("com.android.system.virtualmachine.flags.avf_v_test_apis") @NonNull public java.util.List<java.lang.String> getExtraApks();
+    method @FlaggedApi("com.android.system.virtualmachine.flags.avf_v_test_apis") @NonNull public String getOs();
+    method @Nullable public String getPayloadConfigPath();
+    method public boolean isVmConsoleInputSupported();
+    field @FlaggedApi("com.android.system.virtualmachine.flags.avf_v_test_apis") public static final String MICRODROID = "microdroid";
+  }
+
+  public static final class VirtualMachineConfig.Builder {
+    method @FlaggedApi("com.android.system.virtualmachine.flags.avf_v_test_apis") @NonNull public android.system.virtualmachine.VirtualMachineConfig.Builder addExtraApk(@NonNull String);
+    method @FlaggedApi("com.android.system.virtualmachine.flags.avf_v_test_apis") @NonNull @RequiresPermission(android.system.virtualmachine.VirtualMachine.USE_CUSTOM_VIRTUAL_MACHINE_PERMISSION) 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("com.android.system.virtualmachine.flags.avf_v_test_apis") @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("com.android.system.virtualmachine.flags.avf_v_test_apis") @NonNull public java.util.List<java.lang.String> getSupportedOSList() throws android.system.virtualmachine.VirtualMachineException;
+    method @FlaggedApi("com.android.system.virtualmachine.flags.avf_v_test_apis") @RequiresPermission(android.system.virtualmachine.VirtualMachine.MANAGE_VIRTUAL_MACHINE_PERMISSION) public boolean isFeatureEnabled(String) throws android.system.virtualmachine.VirtualMachineException;
+    method @FlaggedApi("com.android.system.virtualmachine.flags.avf_v_test_apis") @RequiresPermission(android.system.virtualmachine.VirtualMachine.MANAGE_VIRTUAL_MACHINE_PERMISSION) public boolean isRemoteAttestationSupported() throws android.system.virtualmachine.VirtualMachineException;
+    method @FlaggedApi("com.android.system.virtualmachine.flags.avf_v_test_apis") @RequiresPermission(android.system.virtualmachine.VirtualMachine.MANAGE_VIRTUAL_MACHINE_PERMISSION) public boolean isUpdatableVmSupported() throws android.system.virtualmachine.VirtualMachineException;
+    field @FlaggedApi("com.android.system.virtualmachine.flags.avf_v_test_apis") public static final String FEATURE_DICE_CHANGES = "com.android.kvm.DICE_CHANGES";
+    field @FlaggedApi("com.android.system.virtualmachine.flags.avf_v_test_apis") public static final String FEATURE_LLPVM_CHANGES = "com.android.kvm.LLPVM_CHANGES";
+    field @FlaggedApi("com.android.system.virtualmachine.flags.avf_v_test_apis") public static final String FEATURE_MULTI_TENANT = "com.android.kvm.MULTI_TENANT";
+    field public static final String FEATURE_NETWORK = "com.android.kvm.NETWORK";
+    field @FlaggedApi("com.android.system.virtualmachine.flags.avf_v_test_apis") public static final String FEATURE_REMOTE_ATTESTATION = "com.android.kvm.REMOTE_ATTESTATION";
+    field @FlaggedApi("com.android.system.virtualmachine.flags.avf_v_test_apis") public static final String FEATURE_VENDOR_MODULES = "com.android.kvm.VENDOR_MODULES";
+  }
+
+}
+
diff --git a/libs/framework-virtualization/api/test-removed.txt b/libs/framework-virtualization/api/test-removed.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/libs/framework-virtualization/api/test-removed.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/libs/framework-virtualization/jarjar-rules.txt b/libs/framework-virtualization/jarjar-rules.txt
new file mode 100644
index 0000000..726f9aa
--- /dev/null
+++ b/libs/framework-virtualization/jarjar-rules.txt
@@ -0,0 +1,10 @@
+# Rules for the android.system.virtualmachine java_sdk_library.
+
+# Keep the API surface, most of it is accessible from VirtualMachineManager
+keep android.system.virtualmachine.VirtualMachineManager
+# VirtualizationModuleFrameworkInitializer is not accessible from
+# VirtualMachineManager, we need to explicitly keep it.
+keep android.system.virtualmachine.VirtualizationFrameworkInitializer
+
+# We statically link PlatformProperties, rename to avoid clashes.
+rule android.sysprop.** com.android.system.virtualmachine.sysprop.@1
diff --git a/libs/framework-virtualization/lint-baseline.xml b/libs/framework-virtualization/lint-baseline.xml
new file mode 100644
index 0000000..a77a80b
--- /dev/null
+++ b/libs/framework-virtualization/lint-baseline.xml
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<issues format="6" by="lint 8.4.0-alpha08" type="baseline" client="" dependencies="true" name="" variant="all" version="8.4.0-alpha08">
+
+    <issue
+        id="FlaggedApi"
+        message="Method `getExtraApks()` is a flagged API and should be inside an `if (Flags.avfVTestApis())` check (or annotate the surrounding method `createVirtualMachineConfigForAppFrom` with `@FlaggedApi(Flags.FLAG_AVF_V_TEST_APIS) to transfer requirement to caller`)"
+        errorLine1="        if (!vmConfig.getExtraApks().isEmpty()) {"
+        errorLine2="             ~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="packages/modules/Virtualization/libs/framework-virtualization/src/android/system/virtualmachine/VirtualMachine.java"
+            line="1105"
+            column="14"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `getExtraApks()` is a flagged API and should be inside an `if (Flags.avfVTestApis())` check (or annotate the surrounding method `setupExtraApks` with `@FlaggedApi(Flags.FLAG_AVF_V_TEST_APIS) to transfer requirement to caller`)"
+        errorLine1="        List&lt;String> extraApks = config.getExtraApks();"
+        errorLine2="                                 ~~~~~~~~~~~~~~~~~~~~~">
+        <location
+		file="packages/modules/Virtualization/libs/framework-virtualization/src/android/system/virtualmachine/VirtualMachine.java"
+            line="1730"
+            column="34"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `setVendorDiskImage()` is a flagged API and should be inside an `if (Flags.avfVTestApis())` check (or annotate the surrounding method `fromPersistableBundle` with `@FlaggedApi(Flags.FLAG_AVF_V_TEST_APIS) to transfer requirement to caller`)"
+        errorLine1="            builder.setVendorDiskImage(new File(vendorDiskImagePath));"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+		file="packages/modules/Virtualization/libs/framework-virtualization/src/android/system/virtualmachine/VirtualMachineConfig.java"
+            line="367"
+            column="13"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `setOs()` is a flagged API and should be inside an `if (Flags.avfVTestApis())` check (or annotate the surrounding method `fromPersistableBundle` with `@FlaggedApi(Flags.FLAG_AVF_V_TEST_APIS) to transfer requirement to caller`)"
+        errorLine1="        builder.setOs(b.getString(KEY_OS));"
+        errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+		file="packages/modules/Virtualization/libs/framework-virtualization/src/android/system/virtualmachine/VirtualMachineConfig.java"
+            line="370"
+            column="9"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `addExtraApk()` is a flagged API and should be inside an `if (Flags.avfVTestApis())` check (or annotate the surrounding method `fromPersistableBundle` with `@FlaggedApi(Flags.FLAG_AVF_V_TEST_APIS) to transfer requirement to caller`)"
+        errorLine1="                builder.addExtraApk(extraApk);"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+		file="packages/modules/Virtualization/libs/framework-virtualization/src/android/system/virtualmachine/VirtualMachineConfig.java"
+            line="375"
+            column="17"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `MICRODROID` is a flagged API and should be inside an `if (Flags.avfVTestApis())` check (or annotate the surrounding method `?` with `@FlaggedApi(Flags.FLAG_AVF_V_TEST_APIS) to transfer requirement to caller`)"
+        errorLine1="        @OsName private final String DEFAULT_OS = MICRODROID;"
+        errorLine2="                                                  ~~~~~~~~~~">
+        <location
+		file="packages/modules/Virtualization/libs/framework-virtualization/src/android/system/virtualmachine/VirtualMachineConfig.java"
+            line="855"
+            column="51"/>
+    </issue>
+
+</issues>
diff --git a/libs/framework-virtualization/src/android/system/virtualmachine/VirtualMachine.java b/libs/framework-virtualization/src/android/system/virtualmachine/VirtualMachine.java
new file mode 100644
index 0000000..3b16a8a
--- /dev/null
+++ b/libs/framework-virtualization/src/android/system/virtualmachine/VirtualMachine.java
@@ -0,0 +1,2407 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.system.virtualmachine;
+
+import static android.os.ParcelFileDescriptor.AutoCloseInputStream;
+import static android.os.ParcelFileDescriptor.MODE_READ_ONLY;
+import static android.os.ParcelFileDescriptor.MODE_READ_WRITE;
+import static android.system.virtualmachine.VirtualMachineCallback.ERROR_PAYLOAD_CHANGED;
+import static android.system.virtualmachine.VirtualMachineCallback.ERROR_PAYLOAD_INVALID_CONFIG;
+import static android.system.virtualmachine.VirtualMachineCallback.ERROR_PAYLOAD_VERIFICATION_FAILED;
+import static android.system.virtualmachine.VirtualMachineCallback.ERROR_UNKNOWN;
+import static android.system.virtualmachine.VirtualMachineCallback.STOP_REASON_CRASH;
+import static android.system.virtualmachine.VirtualMachineCallback.STOP_REASON_HANGUP;
+import static android.system.virtualmachine.VirtualMachineCallback.STOP_REASON_INFRASTRUCTURE_ERROR;
+import static android.system.virtualmachine.VirtualMachineCallback.STOP_REASON_KILLED;
+import static android.system.virtualmachine.VirtualMachineCallback.STOP_REASON_MICRODROID_FAILED_TO_CONNECT_TO_VIRTUALIZATION_SERVICE;
+import static android.system.virtualmachine.VirtualMachineCallback.STOP_REASON_MICRODROID_INVALID_PAYLOAD_CONFIG;
+import static android.system.virtualmachine.VirtualMachineCallback.STOP_REASON_MICRODROID_PAYLOAD_HAS_CHANGED;
+import static android.system.virtualmachine.VirtualMachineCallback.STOP_REASON_MICRODROID_PAYLOAD_VERIFICATION_FAILED;
+import static android.system.virtualmachine.VirtualMachineCallback.STOP_REASON_MICRODROID_UNKNOWN_RUNTIME_ERROR;
+import static android.system.virtualmachine.VirtualMachineCallback.STOP_REASON_PVM_FIRMWARE_INSTANCE_IMAGE_CHANGED;
+import static android.system.virtualmachine.VirtualMachineCallback.STOP_REASON_PVM_FIRMWARE_PUBLIC_KEY_MISMATCH;
+import static android.system.virtualmachine.VirtualMachineCallback.STOP_REASON_REBOOT;
+import static android.system.virtualmachine.VirtualMachineCallback.STOP_REASON_SHUTDOWN;
+import static android.system.virtualmachine.VirtualMachineCallback.STOP_REASON_START_FAILED;
+import static android.system.virtualmachine.VirtualMachineCallback.STOP_REASON_UNKNOWN;
+import static android.system.virtualmachine.VirtualMachineCallback.STOP_REASON_VIRTUALIZATION_SERVICE_DIED;
+
+import static java.util.Objects.requireNonNull;
+
+import android.annotation.CallbackExecutor;
+import android.annotation.FlaggedApi;
+import android.annotation.IntDef;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
+import android.annotation.SuppressLint;
+import android.annotation.SystemApi;
+import android.annotation.TestApi;
+import android.annotation.WorkerThread;
+import android.content.ComponentCallbacks2;
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.res.Configuration;
+import android.os.Binder;
+import android.os.IBinder;
+import android.os.ParcelFileDescriptor;
+import android.os.RemoteException;
+import android.os.ServiceSpecificException;
+import android.system.ErrnoException;
+import android.system.OsConstants;
+import android.system.virtualizationcommon.DeathReason;
+import android.system.virtualizationcommon.ErrorCode;
+import android.system.virtualizationservice.IVirtualMachine;
+import android.system.virtualizationservice.IVirtualMachineCallback;
+import android.system.virtualizationservice.IVirtualizationService;
+import android.system.virtualizationservice.InputDevice;
+import android.system.virtualizationservice.PartitionType;
+import android.system.virtualizationservice.VirtualMachineAppConfig;
+import android.system.virtualizationservice.VirtualMachineRawConfig;
+import android.system.virtualizationservice.VirtualMachineState;
+import android.util.JsonReader;
+import android.util.Log;
+import android.util.Pair;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.system.virtualmachine.flags.Flags;
+
+import libcore.io.IoBridge;
+import libcore.io.IoUtils;
+
+import java.io.File;
+import java.io.FileDescriptor;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.channels.FileChannel;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.FileAlreadyExistsException;
+import java.nio.file.FileVisitResult;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.SimpleFileVisitor;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.Executor;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.function.Consumer;
+import java.util.zip.ZipFile;
+
+/**
+ * Represents an VM instance, with its own configuration and state. Instances are persistent and are
+ * created or retrieved via {@link VirtualMachineManager}.
+ *
+ * <p>The {@link #run} method actually starts up the VM and allows the payload code to execute. It
+ * will continue until it exits or {@link #stop} is called. Updates on the state of the VM can be
+ * received using {@link #setCallback}. The app can communicate with the VM using {@link
+ * #connectToVsockServer} or {@link #connectVsock}.
+ *
+ * <p>The payload code running inside the VM has access to a set of native APIs; see the <a
+ * href="https://cs.android.com/android/platform/superproject/main/+/main:packages/modules/Virtualization/libs/libvm_payload/README.md">README
+ * file</a> for details.
+ *
+ * <p>Each VM has a unique secret, computed from the APK that contains the code running in it, the
+ * VM configuration, and a random per-instance salt. The secret can be accessed by the payload code
+ * running inside the VM (using {@code AVmPayload_getVmInstanceSecret}) but is not made available
+ * outside it.
+ *
+ * @hide
+ */
+@SystemApi
+public class VirtualMachine implements AutoCloseable {
+    /** The permission needed to create or run a virtual machine. */
+    public static final String MANAGE_VIRTUAL_MACHINE_PERMISSION =
+            "android.permission.MANAGE_VIRTUAL_MACHINE";
+
+    /**
+     * The permission needed to create a virtual machine with more advanced configuration options.
+     */
+    public static final String USE_CUSTOM_VIRTUAL_MACHINE_PERMISSION =
+            "android.permission.USE_CUSTOM_VIRTUAL_MACHINE";
+
+    /**
+     * The lowest port number that can be used to communicate with the virtual machine payload.
+     *
+     * @see #connectToVsockServer
+     * @see #connectVsock
+     */
+    @SuppressLint("MinMaxConstant") // Won't change: see man 7 vsock.
+    public static final long MIN_VSOCK_PORT = 1024;
+
+    /**
+     * The highest port number that can be used to communicate with the virtual machine payload.
+     *
+     * @see #connectToVsockServer
+     * @see #connectVsock
+     */
+    @SuppressLint("MinMaxConstant") // Won't change: see man 7 vsock.
+    public static final long MAX_VSOCK_PORT = (1L << 32) - 1;
+
+    private ParcelFileDescriptor mTouchSock;
+    private ParcelFileDescriptor mKeySock;
+    private ParcelFileDescriptor mMouseSock;
+    private ParcelFileDescriptor mSwitchesSock;
+    private ParcelFileDescriptor mTrackpadSock;
+
+    private enum InputEventType {
+        TOUCH,
+        MOUSE,
+        TRACKPAD
+    }
+
+    private BlockingQueue<Pair<InputEventType, MotionEvent>> mInputEventQueue =
+            new LinkedBlockingQueue<>();
+
+    /**
+     * Status of a virtual machine
+     *
+     * @hide
+     */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(
+            prefix = "STATUS_",
+            value = {STATUS_STOPPED, STATUS_RUNNING, STATUS_DELETED})
+    public @interface Status {}
+
+    /** The virtual machine has just been created, or {@link #stop} was called on it. */
+    public static final int STATUS_STOPPED = 0;
+
+    /** The virtual machine is running. */
+    public static final int STATUS_RUNNING = 1;
+
+    /**
+     * The virtual machine has been deleted. This is an irreversible state. Once a virtual machine
+     * is deleted all its secrets are permanently lost, and it cannot be run. A new virtual machine
+     * with the same name and config may be created, with new and different secrets.
+     */
+    public static final int STATUS_DELETED = 2;
+
+    private static final String TAG = "VirtualMachine";
+
+    /** Name of the directory under the files directory where all VMs created for the app exist. */
+    private static final String VM_DIR = "vm";
+
+    /** Name of the persisted config file for a VM. */
+    private static final String CONFIG_FILE = "config.xml";
+
+    /** Name of the instance image file for a VM. (Not implemented) */
+    private static final String INSTANCE_IMAGE_FILE = "instance.img";
+
+    /** Name of the file for a VM containing Id. */
+    private static final String INSTANCE_ID_FILE = "instance_id";
+
+    /** Name of the idsig file for a VM */
+    private static final String IDSIG_FILE = "idsig";
+
+    /** Name of the idsig files for extra APKs. */
+    private static final String EXTRA_IDSIG_FILE_PREFIX = "extra_idsig_";
+
+    /** Size of the instance image. 10 MB. */
+    private static final long INSTANCE_FILE_SIZE = 10 * 1024 * 1024;
+
+    /** Name of the file backing the encrypted storage */
+    private static final String ENCRYPTED_STORE_FILE = "storage.img";
+
+    /** The package which owns this VM. */
+    @NonNull private final String mPackageName;
+
+    /** Name of this VM within the package. The name should be unique in the package. */
+    @NonNull private final String mName;
+
+    /** Path to the directory containing all the files related to this VM. */
+    @NonNull private final File mVmRootPath;
+
+    /**
+     * Path to the config file for this VM. The config file is where the configuration is persisted.
+     */
+    @NonNull private final File mConfigFilePath;
+
+    /** Path to the instance image file for this VM. */
+    @NonNull private final File mInstanceFilePath;
+
+    /** Path to the idsig file for this VM. */
+    @NonNull private final File mIdsigFilePath;
+
+    /** File that backs the encrypted storage - Will be null if not enabled. */
+    @Nullable private final File mEncryptedStoreFilePath;
+
+    /** File that contains the Id. This is NULL iff FEATURE_LLPVM is disabled */
+    @Nullable private final File mInstanceIdPath;
+
+    /**
+     * Unmodifiable list of extra apks. Apks are specified by the vm config, and corresponding
+     * idsigs are to be generated.
+     */
+    @NonNull private final List<ExtraApkSpec> mExtraApks;
+
+    private class MemoryManagementCallbacks implements ComponentCallbacks2 {
+        @Override
+        public void onConfigurationChanged(@NonNull Configuration newConfig) {}
+
+        @Override
+        public void onLowMemory() {}
+
+        @Override
+        public void onTrimMemory(int level) {
+            int percent;
+
+            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;
+            }
+
+            synchronized (mLock) {
+                try {
+                    if (mVirtualMachine != null) {
+                        long bytes = mConfig.getMemoryBytes();
+                        mVirtualMachine.setMemoryBalloon(bytes * percent / 100);
+                    }
+                } catch (Exception e) {
+                    /* Caller doesn't want our exceptions. Log them instead. */
+                    Log.w(TAG, "TrimMemory failed: ", e);
+                }
+            }
+        }
+    }
+
+    /** Running instance of virtmgr that hosts VirtualizationService for this VM. */
+    @NonNull private final VirtualizationService mVirtualizationService;
+
+    private final MemoryManagementCallbacks mMemoryManagementCallbacks;
+
+    @NonNull private final Context mContext;
+
+    // A note on lock ordering:
+    // You can take mLock while holding VirtualMachineManager.sCreateLock, but not vice versa.
+    // We never take any other lock while holding mCallbackLock; therefore you can
+    // take mCallbackLock while holding any other lock.
+
+    /** Lock protecting our mutable state (other than callbacks). */
+    private final Object mLock = new Object();
+
+    /** Lock protecting callbacks. */
+    private final Object mCallbackLock = new Object();
+
+    private final boolean mVmOutputCaptured;
+
+    private final boolean mVmConsoleInputSupported;
+
+    private final boolean mConnectVmConsole;
+
+    private final Executor mConsoleExecutor = Executors.newSingleThreadExecutor();
+
+    private ExecutorService mInputEventExecutor;
+
+    /** The configuration that is currently associated with this VM. */
+    @GuardedBy("mLock")
+    @NonNull
+    private VirtualMachineConfig mConfig;
+
+    /** Handle to the "running" VM. */
+    @GuardedBy("mLock")
+    @Nullable
+    private IVirtualMachine mVirtualMachine;
+
+    @GuardedBy("mLock")
+    @Nullable
+    private ParcelFileDescriptor mConsoleOutReader;
+
+    @GuardedBy("mLock")
+    @Nullable
+    private ParcelFileDescriptor mConsoleOutWriter;
+
+    @GuardedBy("mLock")
+    @Nullable
+    private ParcelFileDescriptor mConsoleInReader;
+
+    @GuardedBy("mLock")
+    @Nullable
+    private ParcelFileDescriptor mConsoleInWriter;
+
+    @GuardedBy("mLock")
+    @Nullable
+    private ParcelFileDescriptor mTeeConsoleOutReader;
+
+    @GuardedBy("mLock")
+    @Nullable
+    private ParcelFileDescriptor mTeeConsoleOutWriter;
+
+    @GuardedBy("mLock")
+    @Nullable
+    private ParcelFileDescriptor mPtyFd;
+
+    @GuardedBy("mLock")
+    @Nullable
+    private ParcelFileDescriptor mPtsFd;
+
+    @GuardedBy("mLock")
+    @Nullable
+    private String mPtsName;
+
+    @GuardedBy("mLock")
+    @Nullable
+    private ParcelFileDescriptor mLogReader;
+
+    @GuardedBy("mLock")
+    @Nullable
+    private ParcelFileDescriptor mLogWriter;
+
+    @GuardedBy("mLock")
+    private boolean mWasDeleted = false;
+
+    /** The registered callback */
+    @GuardedBy("mCallbackLock")
+    @Nullable
+    private VirtualMachineCallback mCallback;
+
+    /** The executor on which the callback will be executed */
+    @GuardedBy("mCallbackLock")
+    @Nullable
+    private Executor mCallbackExecutor;
+
+    private static class ExtraApkSpec {
+        public final File apk;
+        public final File idsig;
+
+        ExtraApkSpec(File apk, File idsig) {
+            this.apk = apk;
+            this.idsig = idsig;
+        }
+    }
+
+    static {
+        System.loadLibrary("virtualmachine_jni");
+    }
+
+    private VirtualMachine(
+            @NonNull Context context,
+            @NonNull String name,
+            @NonNull VirtualMachineConfig config,
+            @NonNull VirtualizationService service)
+            throws VirtualMachineException {
+        mPackageName = context.getPackageName();
+        mName = requireNonNull(name, "Name must not be null");
+        mConfig = requireNonNull(config, "Config must not be null");
+        mVirtualizationService = service;
+
+        File thisVmDir = getVmDir(context, mName);
+        mVmRootPath = thisVmDir;
+        mConfigFilePath = new File(thisVmDir, CONFIG_FILE);
+        try {
+            mInstanceIdPath =
+                    (mVirtualizationService
+                                    .getBinder()
+                                    .isFeatureEnabled(IVirtualizationService.FEATURE_LLPVM_CHANGES))
+                            ? new File(thisVmDir, INSTANCE_ID_FILE)
+                            : null;
+        } catch (RemoteException e) {
+            throw e.rethrowAsRuntimeException();
+        }
+        mInstanceFilePath = new File(thisVmDir, INSTANCE_IMAGE_FILE);
+        mIdsigFilePath = new File(thisVmDir, IDSIG_FILE);
+        mExtraApks = setupExtraApks(context, config, thisVmDir);
+        mContext = context;
+        mEncryptedStoreFilePath =
+                (config.isEncryptedStorageEnabled())
+                        ? new File(thisVmDir, ENCRYPTED_STORE_FILE)
+                        : null;
+
+        mVmOutputCaptured = config.isVmOutputCaptured();
+        mVmConsoleInputSupported = config.isVmConsoleInputSupported();
+        mConnectVmConsole = config.isConnectVmConsole();
+
+        VirtualMachineCustomImageConfig customImageConfig;
+        customImageConfig = config.getCustomImageConfig();
+        if (customImageConfig == null || customImageConfig.useAutoMemoryBalloon()) {
+            mMemoryManagementCallbacks = new MemoryManagementCallbacks();
+        } else {
+            mMemoryManagementCallbacks = null;
+        }
+    }
+
+    /**
+     * Creates a virtual machine from an {@link VirtualMachineDescriptor} object and associates it
+     * with the given name.
+     *
+     * <p>The new virtual machine will be in the same state as the descriptor indicates.
+     *
+     * <p>Once a virtual machine is imported it is persisted until it is deleted by calling {@link
+     * #delete}. The imported virtual machine is in {@link #STATUS_STOPPED} state. To run the VM,
+     * call {@link #run}.
+     */
+    @GuardedBy("VirtualMachineManager.sCreateLock")
+    @NonNull
+    static VirtualMachine fromDescriptor(
+            @NonNull Context context,
+            @NonNull String name,
+            @NonNull VirtualMachineDescriptor vmDescriptor)
+            throws VirtualMachineException {
+        File vmDir = createVmDir(context, name);
+        try {
+            VirtualMachine vm;
+            try (vmDescriptor) {
+                VirtualMachineConfig config = VirtualMachineConfig.from(vmDescriptor.getConfigFd());
+                vm = new VirtualMachine(context, name, config, VirtualizationService.getInstance());
+                config.serialize(vm.mConfigFilePath);
+                try {
+                    vm.mInstanceFilePath.createNewFile();
+                } catch (IOException e) {
+                    throw new VirtualMachineException("failed to create instance image", e);
+                }
+                vm.importInstanceFrom(vmDescriptor.getInstanceImgFd());
+
+                if (vmDescriptor.getEncryptedStoreFd() != null) {
+                    try {
+                        vm.mEncryptedStoreFilePath.createNewFile();
+                    } catch (IOException e) {
+                        throw new VirtualMachineException(
+                                "failed to create encrypted storage image", e);
+                    }
+                    vm.importEncryptedStoreFrom(vmDescriptor.getEncryptedStoreFd());
+                }
+                if (vm.mInstanceIdPath != null) {
+                    vm.importInstanceIdFrom(vmDescriptor.getInstanceIdFd());
+                    vm.claimInstance();
+                }
+            }
+            return vm;
+        } catch (VirtualMachineException | RuntimeException e) {
+            // If anything goes wrong, delete any files created so far and the VM's directory
+            try {
+                deleteRecursively(vmDir);
+            } catch (Exception innerException) {
+                e.addSuppressed(innerException);
+            }
+            throw e;
+        }
+    }
+
+    /**
+     * Creates a virtual machine with the given name and config. Once a virtual machine is created
+     * it is persisted until it is deleted by calling {@link #delete}. The created virtual machine
+     * is in {@link #STATUS_STOPPED} state. To run the VM, call {@link #run}.
+     */
+    @GuardedBy("VirtualMachineManager.sCreateLock")
+    @NonNull
+    static VirtualMachine create(
+            @NonNull Context context, @NonNull String name, @NonNull VirtualMachineConfig config)
+            throws VirtualMachineException {
+        File vmDir = createVmDir(context, name);
+
+        try {
+            VirtualMachine vm =
+                    new VirtualMachine(context, name, config, VirtualizationService.getInstance());
+            config.serialize(vm.mConfigFilePath);
+            try {
+                vm.mInstanceFilePath.createNewFile();
+            } catch (IOException e) {
+                throw new VirtualMachineException("failed to create instance image", e);
+            }
+            if (config.isEncryptedStorageEnabled()) {
+                try {
+                    vm.mEncryptedStoreFilePath.createNewFile();
+                } catch (IOException e) {
+                    throw new VirtualMachineException(
+                            "failed to create encrypted storage image", e);
+                }
+            }
+
+            IVirtualizationService service = vm.mVirtualizationService.getBinder();
+
+            if (vm.mInstanceIdPath != null) {
+                try (FileOutputStream stream = new FileOutputStream(vm.mInstanceIdPath)) {
+                    byte[] id = service.allocateInstanceId();
+                    stream.write(id);
+                } catch (FileNotFoundException e) {
+                    throw new VirtualMachineException("instance_id file missing", e);
+                } catch (IOException e) {
+                    throw new VirtualMachineException("failed to persist instance_id", e);
+                } catch (RemoteException e) {
+                    throw e.rethrowAsRuntimeException();
+                } catch (ServiceSpecificException | IllegalArgumentException e) {
+                    throw new VirtualMachineException("failed to create instance_id", e);
+                }
+            }
+
+            try {
+                service.initializeWritablePartition(
+                        ParcelFileDescriptor.open(vm.mInstanceFilePath, MODE_READ_WRITE),
+                        INSTANCE_FILE_SIZE,
+                        PartitionType.ANDROID_VM_INSTANCE);
+            } catch (FileNotFoundException e) {
+                throw new VirtualMachineException("instance image missing", e);
+            } catch (RemoteException e) {
+                throw e.rethrowAsRuntimeException();
+            } catch (ServiceSpecificException | IllegalArgumentException e) {
+                throw new VirtualMachineException("failed to create instance partition", e);
+            }
+
+            if (config.isEncryptedStorageEnabled()) {
+                try {
+                    service.initializeWritablePartition(
+                            ParcelFileDescriptor.open(vm.mEncryptedStoreFilePath, MODE_READ_WRITE),
+                            config.getEncryptedStorageBytes(),
+                            PartitionType.ENCRYPTEDSTORE);
+                } catch (FileNotFoundException e) {
+                    throw new VirtualMachineException("encrypted storage image missing", e);
+                } catch (RemoteException e) {
+                    throw e.rethrowAsRuntimeException();
+                } catch (ServiceSpecificException | IllegalArgumentException e) {
+                    throw new VirtualMachineException(
+                            "failed to create encrypted storage partition", e);
+                }
+            }
+            return vm;
+        } catch (VirtualMachineException | RuntimeException e) {
+            // If anything goes wrong, delete any files created so far and the VM's directory
+            try {
+                vmInstanceCleanup(context, name);
+            } catch (Exception innerException) {
+                e.addSuppressed(innerException);
+            }
+            throw e;
+        }
+    }
+
+    /** Loads a virtual machine that is already created before. */
+    @GuardedBy("VirtualMachineManager.sCreateLock")
+    @Nullable
+    static VirtualMachine load(@NonNull Context context, @NonNull String name)
+            throws VirtualMachineException {
+        File thisVmDir = getVmDir(context, name);
+        if (!thisVmDir.exists()) {
+            // The VM doesn't exist.
+            return null;
+        }
+        File configFilePath = new File(thisVmDir, CONFIG_FILE);
+        VirtualMachineConfig config = VirtualMachineConfig.from(configFilePath);
+        VirtualMachine vm =
+                new VirtualMachine(context, name, config, VirtualizationService.getInstance());
+
+        if (vm.mInstanceIdPath != null && !vm.mInstanceIdPath.exists()) {
+            throw new VirtualMachineException("instance_id file missing");
+        }
+        if (!vm.mInstanceFilePath.exists()) {
+            throw new VirtualMachineException("instance image missing");
+        }
+        if (config.isEncryptedStorageEnabled() && !vm.mEncryptedStoreFilePath.exists()) {
+            throw new VirtualMachineException("Storage image missing");
+        }
+        return vm;
+    }
+
+    @GuardedBy("VirtualMachineManager.sCreateLock")
+    void delete(Context context, String name) throws VirtualMachineException {
+        synchronized (mLock) {
+            checkStopped();
+            // Once we explicitly delete a VM it must remain permanently in the deleted state;
+            // if a new VM is created with the same name (and files) that's unrelated.
+            mWasDeleted = true;
+        }
+        vmInstanceCleanup(context, name);
+    }
+
+    // Delete the full VM directory and notify VirtualizationService to remove this
+    // VM instance for housekeeping.
+    @GuardedBy("VirtualMachineManager.sCreateLock")
+    static void vmInstanceCleanup(Context context, String name) throws VirtualMachineException {
+        File vmDir = getVmDir(context, name);
+        notifyInstanceRemoval(vmDir, VirtualizationService.getInstance());
+        try {
+            deleteRecursively(vmDir);
+        } catch (IOException e) {
+            throw new VirtualMachineException(e);
+        }
+    }
+
+    private static void notifyInstanceRemoval(
+            File vmDirectory, @NonNull VirtualizationService service) {
+        File instanceIdFile = new File(vmDirectory, INSTANCE_ID_FILE);
+        try {
+            byte[] instanceId = Files.readAllBytes(instanceIdFile.toPath());
+            service.getBinder().removeVmInstance(instanceId);
+        } catch (Exception e) {
+            // Deliberately ignoring error in removing VM instance. This potentially leads to
+            // unaccounted instances in the VS' database. But, nothing much can be done by caller.
+            Log.w(TAG, "Failed to notify VS to remove the VM instance", e);
+        }
+    }
+
+    // Claim the instance. This notifies the global VS about the ownership of this
+    // instance_id for housekeeping purpose.
+    void claimInstance() throws VirtualMachineException {
+        if (mInstanceIdPath != null) {
+            IVirtualizationService service = mVirtualizationService.getBinder();
+            try {
+                byte[] instanceId = Files.readAllBytes(mInstanceIdPath.toPath());
+                service.claimVmInstance(instanceId);
+            } catch (IOException e) {
+                throw new VirtualMachineException("failed to read instance_id", e);
+            } catch (RemoteException e) {
+                throw e.rethrowAsRuntimeException();
+            }
+        }
+    }
+
+    @GuardedBy("VirtualMachineManager.sCreateLock")
+    @NonNull
+    private static File createVmDir(@NonNull Context context, @NonNull String name)
+            throws VirtualMachineException {
+        File vmDir = getVmDir(context, name);
+        try {
+            // We don't need to undo this even if VM creation fails.
+            Files.createDirectories(vmDir.getParentFile().toPath());
+
+            // The checking of the existence of this directory and the creation of it is done
+            // atomically. If the directory already exists (i.e. the VM with the same name was
+            // already created), FileAlreadyExistsException is thrown.
+            Files.createDirectory(vmDir.toPath());
+        } catch (FileAlreadyExistsException e) {
+            throw new VirtualMachineException("virtual machine already exists", e);
+        } catch (IOException e) {
+            throw new VirtualMachineException("failed to create directory for VM", e);
+        }
+        return vmDir;
+    }
+
+    @NonNull
+    private static File getVmDir(@NonNull Context context, @NonNull String name) {
+        if (name.contains(File.separator) || name.equals(".") || name.equals("..")) {
+            throw new IllegalArgumentException("Invalid VM name: " + name);
+        }
+        File vmRoot = new File(context.getDataDir(), VM_DIR);
+        return new File(vmRoot, name);
+    }
+
+    /**
+     * Returns the name of this virtual machine. The name is unique in the package and can't be
+     * changed.
+     *
+     * @hide
+     */
+    @SystemApi
+    @NonNull
+    public String getName() {
+        return mName;
+    }
+
+    /**
+     * Returns the currently selected config of this virtual machine. There can be multiple virtual
+     * machines sharing the same config. Even in that case, the virtual machines are completely
+     * isolated from each other; they have different secrets. It is also possible that a virtual
+     * machine can change its config, which can be done by calling {@link #setConfig}.
+     *
+     * <p>NOTE: This method may block and should not be called on the main thread.
+     *
+     * @hide
+     */
+    @SystemApi
+    @WorkerThread
+    @NonNull
+    public VirtualMachineConfig getConfig() {
+        synchronized (mLock) {
+            return mConfig;
+        }
+    }
+
+    /**
+     * Returns the current status of this virtual machine.
+     *
+     * <p>NOTE: This method may block and should not be called on the main thread.
+     *
+     * @hide
+     */
+    @SystemApi
+    @WorkerThread
+    @Status
+    public int getStatus() {
+        IVirtualMachine virtualMachine;
+        synchronized (mLock) {
+            if (mWasDeleted) {
+                return STATUS_DELETED;
+            }
+            virtualMachine = mVirtualMachine;
+        }
+
+        int status;
+        if (virtualMachine == null) {
+            status = STATUS_STOPPED;
+        } else {
+            try {
+                status = stateToStatus(virtualMachine.getState());
+            } catch (RemoteException e) {
+                throw e.rethrowAsRuntimeException();
+            }
+        }
+        if (status == STATUS_STOPPED && !mVmRootPath.exists()) {
+            // A VM can quite happily keep running if its backing files have been deleted.
+            // But once it stops, it's gone forever.
+            synchronized (mLock) {
+                dropVm();
+            }
+            return STATUS_DELETED;
+        }
+        return status;
+    }
+
+    private int stateToStatus(@VirtualMachineState int state) {
+        switch (state) {
+            case VirtualMachineState.STARTING:
+            case VirtualMachineState.STARTED:
+            case VirtualMachineState.READY:
+            case VirtualMachineState.FINISHED:
+                return STATUS_RUNNING;
+            case VirtualMachineState.NOT_STARTED:
+            case VirtualMachineState.DEAD:
+            default:
+                return STATUS_STOPPED;
+        }
+    }
+
+    // Throw an appropriate exception if we have a running VM, or the VM has been deleted.
+    @GuardedBy("mLock")
+    private void checkStopped() throws VirtualMachineException {
+        if (mWasDeleted || !mVmRootPath.exists()) {
+            throw new VirtualMachineException("VM has been deleted");
+        }
+        if (mVirtualMachine == null) {
+            return;
+        }
+        try {
+            if (stateToStatus(mVirtualMachine.getState()) != STATUS_STOPPED) {
+                throw new VirtualMachineException("VM is not in stopped state");
+            }
+        } catch (RemoteException e) {
+            throw e.rethrowAsRuntimeException();
+        }
+        // It's stopped, but we still have a reference to it - we can fix that.
+        dropVm();
+    }
+
+    /**
+     * This should only be called when we know our VM has stopped; we no longer need to hold a
+     * reference to it (this allows resources to be GC'd) and we no longer need to be informed of
+     * memory pressure.
+     */
+    @GuardedBy("mLock")
+    private void dropVm() {
+        if (mMemoryManagementCallbacks != null) {
+            mContext.unregisterComponentCallbacks(mMemoryManagementCallbacks);
+        }
+        mVirtualMachine = null;
+    }
+
+    /** If we have an IVirtualMachine in the running state return it, otherwise throw. */
+    @GuardedBy("mLock")
+    private IVirtualMachine getRunningVm() throws VirtualMachineException {
+        try {
+            if (mVirtualMachine != null
+                    && stateToStatus(mVirtualMachine.getState()) == STATUS_RUNNING) {
+                return mVirtualMachine;
+            } else {
+                if (mWasDeleted || !mVmRootPath.exists()) {
+                    throw new VirtualMachineException("VM has been deleted");
+                } else {
+                    throw new VirtualMachineException("VM is not in running state");
+                }
+            }
+        } catch (RemoteException e) {
+            throw e.rethrowAsRuntimeException();
+        }
+    }
+
+    /**
+     * Registers the callback object to get events from the virtual machine. If a callback was
+     * already registered, it is replaced with the new one.
+     *
+     * @hide
+     */
+    @SystemApi
+    public void setCallback(
+            @NonNull @CallbackExecutor Executor executor,
+            @NonNull VirtualMachineCallback callback) {
+        synchronized (mCallbackLock) {
+            mCallback = callback;
+            mCallbackExecutor = executor;
+        }
+    }
+
+    /**
+     * Clears the currently registered callback.
+     *
+     * @hide
+     */
+    @SystemApi
+    public void clearCallback() {
+        synchronized (mCallbackLock) {
+            mCallback = null;
+            mCallbackExecutor = null;
+        }
+    }
+
+    /** Executes a callback on the callback executor. */
+    private void executeCallback(Consumer<VirtualMachineCallback> fn) {
+        final VirtualMachineCallback callback;
+        final Executor executor;
+        synchronized (mCallbackLock) {
+            callback = mCallback;
+            executor = mCallbackExecutor;
+        }
+        if (callback == null || executor == null) {
+            return;
+        }
+        final long restoreToken = Binder.clearCallingIdentity();
+        try {
+            executor.execute(() -> fn.accept(callback));
+        } finally {
+            Binder.restoreCallingIdentity(restoreToken);
+        }
+    }
+
+    private android.system.virtualizationservice.VirtualMachineConfig
+            createVirtualMachineConfigForRawFrom(VirtualMachineConfig vmConfig)
+                    throws IllegalStateException, IOException {
+        VirtualMachineRawConfig rawConfig = vmConfig.toVsRawConfig();
+
+        // Handle input devices here
+        List<InputDevice> inputDevices = new ArrayList<>();
+        if (vmConfig.getCustomImageConfig() != null && rawConfig.displayConfig != null) {
+            if (vmConfig.getCustomImageConfig().useTouch()) {
+                ParcelFileDescriptor[] pfds = ParcelFileDescriptor.createSocketPair();
+                mTouchSock = pfds[0];
+                InputDevice.MultiTouch t = new InputDevice.MultiTouch();
+                t.width = rawConfig.displayConfig.width;
+                t.height = rawConfig.displayConfig.height;
+                t.pfd = pfds[1];
+                inputDevices.add(InputDevice.multiTouch(t));
+            }
+            if (vmConfig.getCustomImageConfig().useKeyboard()) {
+                ParcelFileDescriptor[] pfds = ParcelFileDescriptor.createSocketPair();
+                mKeySock = pfds[0];
+                InputDevice.Keyboard k = new InputDevice.Keyboard();
+                k.pfd = pfds[1];
+                inputDevices.add(InputDevice.keyboard(k));
+            }
+            if (vmConfig.getCustomImageConfig().useMouse()) {
+                ParcelFileDescriptor[] pfds = ParcelFileDescriptor.createSocketPair();
+                mMouseSock = pfds[0];
+                InputDevice.Mouse m = new InputDevice.Mouse();
+                m.pfd = pfds[1];
+                inputDevices.add(InputDevice.mouse(m));
+            }
+            if (vmConfig.getCustomImageConfig().useSwitches()) {
+                ParcelFileDescriptor[] pfds = ParcelFileDescriptor.createSocketPair();
+                mSwitchesSock = pfds[0];
+                InputDevice.Switches s = new InputDevice.Switches();
+                s.pfd = pfds[1];
+                inputDevices.add(InputDevice.switches(s));
+            }
+            if (vmConfig.getCustomImageConfig().useTrackpad()) {
+                ParcelFileDescriptor[] pfds = ParcelFileDescriptor.createSocketPair();
+                mTrackpadSock = pfds[0];
+                InputDevice.Trackpad t = new InputDevice.Trackpad();
+                // TODO(b/347253952): make it configurable
+                t.width = 2380;
+                t.height = 1369;
+                t.pfd = pfds[1];
+                inputDevices.add(InputDevice.trackpad(t));
+            }
+        }
+        rawConfig.inputDevices = inputDevices.toArray(new InputDevice[0]);
+
+        // Handle network support
+        if (vmConfig.getCustomImageConfig() != null) {
+            rawConfig.networkSupported = vmConfig.getCustomImageConfig().useNetwork();
+        }
+
+        return android.system.virtualizationservice.VirtualMachineConfig.rawConfig(rawConfig);
+    }
+
+    private static record InputEvent(short type, short code, int value) {}
+
+    /** @hide */
+    public boolean sendKeyEvent(KeyEvent event) {
+        if (mKeySock == null) {
+            Log.d(TAG, "mKeySock == null");
+            return false;
+        }
+        // from include/uapi/linux/input-event-codes.h in the kernel.
+        short EV_SYN = 0x00;
+        short EV_KEY = 0x01;
+        short SYN_REPORT = 0x00;
+        boolean down = event.getAction() != MotionEvent.ACTION_UP;
+
+        return writeEventsToSock(
+                mKeySock,
+                Arrays.asList(
+                        new InputEvent(EV_KEY, (short) event.getScanCode(), down ? 1 : 0),
+                        new InputEvent(EV_SYN, SYN_REPORT, 0)));
+    }
+
+    /** @hide */
+    public boolean sendMouseEvent(MotionEvent event) {
+        try {
+            mInputEventQueue.add(
+                    Pair.create(InputEventType.MOUSE, MotionEvent.obtainNoHistory(event)));
+            return true;
+        } catch (Exception e) {
+            Log.e(TAG, e.toString());
+            return false;
+        }
+    }
+
+    /** @hide */
+    private boolean sendMouseEventInternal(MotionEvent event) {
+        if (mMouseSock == null) {
+            Log.d(TAG, "mMouseSock == null");
+            return false;
+        }
+        // from include/uapi/linux/input-event-codes.h in the kernel.
+        short EV_SYN = 0x00;
+        short EV_REL = 0x02;
+        short EV_KEY = 0x01;
+        short REL_X = 0x00;
+        short REL_Y = 0x01;
+        short SYN_REPORT = 0x00;
+        switch (event.getAction()) {
+            case MotionEvent.ACTION_MOVE:
+                int x = (int) event.getX();
+                int y = (int) event.getY();
+                return writeEventsToSock(
+                        mMouseSock,
+                        Arrays.asList(
+                                new InputEvent(EV_REL, REL_X, x),
+                                new InputEvent(EV_REL, REL_Y, y),
+                                new InputEvent(EV_SYN, SYN_REPORT, 0)));
+            case MotionEvent.ACTION_BUTTON_PRESS:
+            case MotionEvent.ACTION_BUTTON_RELEASE:
+                short BTN_LEFT = 0x110;
+                short BTN_RIGHT = 0x111;
+                short BTN_MIDDLE = 0x112;
+                short keyCode;
+                switch (event.getActionButton()) {
+                    case MotionEvent.BUTTON_PRIMARY:
+                        keyCode = BTN_LEFT;
+                        break;
+                    case MotionEvent.BUTTON_SECONDARY:
+                        keyCode = BTN_RIGHT;
+                        break;
+                    case MotionEvent.BUTTON_TERTIARY:
+                        keyCode = BTN_MIDDLE;
+                        break;
+                    default:
+                        Log.d(TAG, event.toString());
+                        return false;
+                }
+                return writeEventsToSock(
+                        mMouseSock,
+                        Arrays.asList(
+                                new InputEvent(
+                                        EV_KEY,
+                                        keyCode,
+                                        event.getAction() == MotionEvent.ACTION_BUTTON_PRESS
+                                                ? 1
+                                                : 0),
+                                new InputEvent(EV_SYN, SYN_REPORT, 0)));
+            case MotionEvent.ACTION_SCROLL:
+                short REL_HWHEEL = 0x06;
+                short REL_WHEEL = 0x08;
+                int scrollX = (int) event.getAxisValue(MotionEvent.AXIS_HSCROLL);
+                int scrollY = (int) event.getAxisValue(MotionEvent.AXIS_VSCROLL);
+                boolean status = true;
+                if (scrollX != 0) {
+                    status &=
+                            writeEventsToSock(
+                                    mMouseSock,
+                                    Arrays.asList(
+                                            new InputEvent(EV_REL, REL_HWHEEL, scrollX),
+                                            new InputEvent(EV_SYN, SYN_REPORT, 0)));
+                } else if (scrollY != 0) {
+                    status &=
+                            writeEventsToSock(
+                                    mMouseSock,
+                                    Arrays.asList(
+                                            new InputEvent(EV_REL, REL_WHEEL, scrollY),
+                                            new InputEvent(EV_SYN, SYN_REPORT, 0)));
+                } else {
+                    Log.d(TAG, event.toString());
+                    return false;
+                }
+                return status;
+            case MotionEvent.ACTION_UP:
+            case MotionEvent.ACTION_DOWN:
+                // Ignored because it's handled by ACTION_BUTTON_PRESS and ACTION_BUTTON_RELEASE
+                return true;
+            default:
+                Log.d(TAG, event.toString());
+                return false;
+        }
+    }
+
+    /** @hide */
+    public boolean sendMultiTouchEvent(MotionEvent event) {
+        try {
+            mInputEventQueue.add(
+                    Pair.create(InputEventType.TOUCH, MotionEvent.obtainNoHistory(event)));
+            return true;
+        } catch (Exception e) {
+            Log.e(TAG, e.toString());
+            return false;
+        }
+    }
+
+    /** @hide */
+    private boolean sendMultiTouchEventInternal(MotionEvent event) {
+        if (mTouchSock == null) {
+            Log.d(TAG, "mTouchSock == null");
+            return false;
+        }
+        // from include/uapi/linux/input-event-codes.h in the kernel.
+        short EV_SYN = 0x00;
+        short EV_ABS = 0x03;
+        short EV_KEY = 0x01;
+        short BTN_TOUCH = 0x14a;
+        short ABS_X = 0x00;
+        short ABS_Y = 0x01;
+        short SYN_REPORT = 0x00;
+        short ABS_MT_SLOT = 0x2f;
+        short ABS_MT_POSITION_X = 0x35;
+        short ABS_MT_POSITION_Y = 0x36;
+        short ABS_MT_TRACKING_ID = 0x39;
+
+        switch (event.getActionMasked()) {
+            case MotionEvent.ACTION_MOVE:
+                List<InputEvent> events =
+                        new ArrayList<>(
+                                event.getPointerCount() * 6 /*InputEvent per a pointer*/
+                                        + 1 /*SYN*/);
+                for (int actionIdx = 0; actionIdx < event.getPointerCount(); actionIdx++) {
+                    int pointerId = event.getPointerId(actionIdx);
+                    int x = (int) event.getRawX(actionIdx);
+                    int y = (int) event.getRawY(actionIdx);
+                    events.add(new InputEvent(EV_ABS, ABS_MT_SLOT, pointerId));
+                    events.add(new InputEvent(EV_ABS, ABS_MT_TRACKING_ID, pointerId));
+                    events.add(new InputEvent(EV_ABS, ABS_MT_POSITION_X, x));
+                    events.add(new InputEvent(EV_ABS, ABS_MT_POSITION_Y, y));
+                    events.add(new InputEvent(EV_ABS, ABS_X, x));
+                    events.add(new InputEvent(EV_ABS, ABS_Y, y));
+                }
+                events.add(new InputEvent(EV_SYN, SYN_REPORT, 0));
+                return writeEventsToSock(mTouchSock, events);
+            case MotionEvent.ACTION_DOWN:
+            case MotionEvent.ACTION_POINTER_DOWN:
+            case MotionEvent.ACTION_UP:
+            case MotionEvent.ACTION_POINTER_UP:
+                break;
+            default:
+                return false;
+        }
+
+        boolean down =
+                event.getActionMasked() == MotionEvent.ACTION_DOWN
+                        || event.getActionMasked() == MotionEvent.ACTION_POINTER_DOWN;
+        int actionIdx = event.getActionIndex();
+        int pointerId = event.getPointerId(actionIdx);
+        int x = (int) event.getRawX(actionIdx);
+        int y = (int) event.getRawY(actionIdx);
+        return writeEventsToSock(
+                mTouchSock,
+                Arrays.asList(
+                        new InputEvent(EV_KEY, BTN_TOUCH, down ? 1 : 0),
+                        new InputEvent(EV_ABS, ABS_MT_SLOT, pointerId),
+                        new InputEvent(EV_ABS, ABS_MT_TRACKING_ID, down ? pointerId : -1),
+                        new InputEvent(EV_ABS, ABS_MT_POSITION_X, x),
+                        new InputEvent(EV_ABS, ABS_MT_POSITION_Y, y),
+                        new InputEvent(EV_ABS, ABS_X, x),
+                        new InputEvent(EV_ABS, ABS_Y, y),
+                        new InputEvent(EV_SYN, SYN_REPORT, 0)));
+    }
+
+    /** @hide */
+    public boolean sendLidEvent(boolean close) {
+        if (mSwitchesSock == null) {
+            Log.d(TAG, "mSwitcheSock == null");
+            return false;
+        }
+
+        // from include/uapi/linux/input-event-codes.h in the kernel.
+        short EV_SYN = 0x00;
+        short EV_SW = 0x05;
+        short SW_LID = 0x00;
+        short SYN_REPORT = 0x00;
+        return writeEventsToSock(
+                mSwitchesSock,
+                Arrays.asList(
+                        new InputEvent(EV_SW, SW_LID, close ? 1 : 0),
+                        new InputEvent(EV_SYN, SYN_REPORT, 0)));
+    }
+
+    /** @hide */
+    public boolean sendTabletModeEvent(boolean tabletMode) {
+        if (mSwitchesSock == null) {
+            Log.d(TAG, "mSwitcheSock == null");
+            return false;
+        }
+
+        // from include/uapi/linux/input-event-codes.h in the kernel.
+        short EV_SYN = 0x00;
+        short EV_SW = 0x05;
+        short SW_TABLET_MODE = 0x01;
+        short SYN_REPORT = 0x00;
+        return writeEventsToSock(
+                mSwitchesSock,
+                Arrays.asList(
+                        new InputEvent(EV_SW, SW_TABLET_MODE, tabletMode ? 1 : 0),
+                        new InputEvent(EV_SYN, SYN_REPORT, 0)));
+    }
+
+    /** @hide */
+    public boolean sendTrackpadEvent(MotionEvent event) {
+        try {
+            mInputEventQueue.add(
+                    Pair.create(InputEventType.TRACKPAD, MotionEvent.obtainNoHistory(event)));
+            return true;
+        } catch (Exception e) {
+            Log.e(TAG, e.toString());
+            return false;
+        }
+    }
+
+    /** @hide */
+    private boolean sendTrackpadEventInternal(MotionEvent event) {
+        if (mTrackpadSock == null) {
+            Log.d(TAG, "mTrackpadSock == null");
+            return false;
+        }
+        // from include/uapi/linux/input-event-codes.h in the kernel.
+        short EV_SYN = 0x00;
+        short EV_ABS = 0x03;
+        short EV_KEY = 0x01;
+        short BTN_TOUCH = 0x14a;
+        short BTN_TOOL_FINGER = 0x145;
+        short BTN_TOOL_DOUBLETAP = 0x14d;
+        short BTN_TOOL_TRIPLETAP = 0x14e;
+        short BTN_TOOL_QUADTAP = 0x14f;
+        short ABS_X = 0x00;
+        short ABS_Y = 0x01;
+        short SYN_REPORT = 0x00;
+        short ABS_MT_SLOT = 0x2f;
+        short ABS_MT_TOUCH_MAJOR = 0x30;
+        short ABS_MT_TOUCH_MINOR = 0x31;
+        short ABS_MT_WIDTH_MAJOR = 0x32;
+        short ABS_MT_WIDTH_MINOR = 0x33;
+        short ABS_MT_ORIENTATION = 0x34;
+        short ABS_MT_POSITION_X = 0x35;
+        short ABS_MT_POSITION_Y = 0x36;
+        short ABS_MT_TOOL_TYPE = 0x37;
+        short ABS_MT_BLOB_ID = 0x38;
+        short ABS_MT_TRACKING_ID = 0x39;
+        short ABS_MT_PRESSURE = 0x3a;
+        short ABS_MT_DISTANCE = 0x3b;
+        short ABS_MT_TOOL_X = 0x3c;
+        short ABS_MT_TOOL_Y = 0x3d;
+        short ABS_PRESSURE = 0x18;
+        short ABS_TOOL_WIDTH = 0x1c;
+
+        switch (event.getActionMasked()) {
+            case MotionEvent.ACTION_BUTTON_PRESS:
+            case MotionEvent.ACTION_BUTTON_RELEASE:
+                short BTN_LEFT = 0x110;
+                short keyCode;
+                switch (event.getActionButton()) {
+                    case MotionEvent.BUTTON_PRIMARY:
+                        keyCode = BTN_LEFT;
+                        break;
+                    default:
+                        Log.d(TAG, event.toString());
+                        return false;
+                }
+                return writeEventsToSock(
+                        mMouseSock,
+                        Arrays.asList(
+                                new InputEvent(
+                                        EV_KEY,
+                                        keyCode,
+                                        event.getAction() == MotionEvent.ACTION_BUTTON_PRESS
+                                                ? 1
+                                                : 0),
+                                new InputEvent(EV_SYN, SYN_REPORT, 0)));
+            case MotionEvent.ACTION_MOVE:
+                List<InputEvent> events =
+                        new ArrayList<>(
+                                event.getPointerCount() * 10 /*InputEvent per a pointer*/
+                                        + 1 /*SYN*/);
+                for (int actionIdx = 0; actionIdx < event.getPointerCount(); actionIdx++) {
+                    int pointerId = event.getPointerId(actionIdx);
+                    int x = (int) event.getRawX(actionIdx);
+                    int y = (int) event.getRawY(actionIdx);
+                    events.add(new InputEvent(EV_ABS, ABS_MT_SLOT, pointerId));
+                    events.add(new InputEvent(EV_ABS, ABS_MT_TRACKING_ID, pointerId));
+                    events.add(new InputEvent(EV_ABS, ABS_MT_POSITION_X, x));
+                    events.add(new InputEvent(EV_ABS, ABS_MT_POSITION_Y, y));
+                    events.add(
+                            new InputEvent(
+                                    EV_ABS,
+                                    ABS_MT_TOUCH_MAJOR,
+                                    (short) event.getTouchMajor(actionIdx)));
+                    events.add(
+                            new InputEvent(
+                                    EV_ABS,
+                                    ABS_MT_TOUCH_MINOR,
+                                    (short) event.getTouchMinor(actionIdx)));
+                    events.add(new InputEvent(EV_ABS, ABS_X, x));
+                    events.add(new InputEvent(EV_ABS, ABS_Y, y));
+                    events.add(
+                            new InputEvent(
+                                    EV_ABS,
+                                    ABS_PRESSURE,
+                                    (short) (255 * event.getPressure(actionIdx))));
+                    events.add(
+                            new InputEvent(
+                                    EV_ABS,
+                                    ABS_MT_PRESSURE,
+                                    (short) (255 * event.getPressure(actionIdx))));
+                }
+                events.add(new InputEvent(EV_SYN, SYN_REPORT, 0));
+                return writeEventsToSock(mTrackpadSock, events);
+            case MotionEvent.ACTION_DOWN:
+            case MotionEvent.ACTION_POINTER_DOWN:
+            case MotionEvent.ACTION_UP:
+            case MotionEvent.ACTION_POINTER_UP:
+                break;
+            default:
+                return false;
+        }
+
+        boolean down =
+                event.getActionMasked() == MotionEvent.ACTION_DOWN
+                        || event.getActionMasked() == MotionEvent.ACTION_POINTER_DOWN;
+        int actionIdx = event.getActionIndex();
+        int pointerId = event.getPointerId(actionIdx);
+        int x = (int) event.getRawX(actionIdx);
+        int y = (int) event.getRawY(actionIdx);
+        return writeEventsToSock(
+                mTrackpadSock,
+                Arrays.asList(
+                        new InputEvent(EV_KEY, BTN_TOUCH, down ? 1 : 0),
+                        new InputEvent(
+                                EV_KEY,
+                                BTN_TOOL_FINGER,
+                                down && event.getPointerCount() == 1 ? 1 : 0),
+                        new InputEvent(
+                                EV_KEY, BTN_TOOL_DOUBLETAP, event.getPointerCount() == 2 ? 1 : 0),
+                        new InputEvent(
+                                EV_KEY, BTN_TOOL_TRIPLETAP, event.getPointerCount() == 3 ? 1 : 0),
+                        new InputEvent(
+                                EV_KEY, BTN_TOOL_QUADTAP, event.getPointerCount() > 4 ? 1 : 0),
+                        new InputEvent(EV_ABS, ABS_MT_SLOT, pointerId),
+                        new InputEvent(EV_ABS, ABS_MT_TRACKING_ID, down ? pointerId : -1),
+                        new InputEvent(EV_ABS, ABS_MT_TOOL_TYPE, 0 /* MT_TOOL_FINGER */),
+                        new InputEvent(EV_ABS, ABS_MT_POSITION_X, x),
+                        new InputEvent(EV_ABS, ABS_MT_POSITION_Y, y),
+                        new InputEvent(
+                                EV_ABS, ABS_MT_TOUCH_MAJOR, (short) event.getTouchMajor(actionIdx)),
+                        new InputEvent(
+                                EV_ABS, ABS_MT_TOUCH_MINOR, (short) event.getTouchMinor(actionIdx)),
+                        new InputEvent(EV_ABS, ABS_X, x),
+                        new InputEvent(EV_ABS, ABS_Y, y),
+                        new InputEvent(
+                                EV_ABS, ABS_PRESSURE, (short) (255 * event.getPressure(actionIdx))),
+                        new InputEvent(
+                                EV_ABS,
+                                ABS_MT_PRESSURE,
+                                (short) (255 * event.getPressure(actionIdx))),
+                        new InputEvent(EV_SYN, SYN_REPORT, 0)));
+    }
+
+    /** @hide */
+    public long getMemoryBalloon() {
+        long bytes = 0;
+
+        if (mMemoryManagementCallbacks != null) {
+            Log.d(TAG, "Auto balloon enabled in getMemoryBalloon");
+            return bytes;
+        }
+
+        synchronized (mLock) {
+            try {
+                if (mVirtualMachine != null) {
+                    bytes = mVirtualMachine.getMemoryBalloon();
+                }
+            } catch (RemoteException e) {
+                Log.w(TAG, "Cannot getMemoryBalloon", e);
+            }
+        }
+
+        return bytes;
+    }
+
+    /** @hide */
+    public void setMemoryBalloon(long bytes) {
+        if (mMemoryManagementCallbacks != null) {
+            Log.d(TAG, "Auto balloon enabled in setMemoryBalloon");
+            return;
+        }
+
+        synchronized (mLock) {
+            try {
+                if (mVirtualMachine != null) {
+                    mVirtualMachine.setMemoryBalloon(bytes);
+                }
+            } catch (RemoteException e) {
+                Log.w(TAG, "Cannot setMemoryBalloon", e);
+            }
+        }
+    }
+
+    private boolean writeEventsToSock(ParcelFileDescriptor sock, List<InputEvent> evtList) {
+        ByteBuffer byteBuffer =
+                ByteBuffer.allocate(8 /* (type: u16 + code: u16 + value: i32) */ * evtList.size());
+        byteBuffer.clear();
+        byteBuffer.order(ByteOrder.LITTLE_ENDIAN);
+        for (InputEvent e : evtList) {
+            byteBuffer.putShort(e.type);
+            byteBuffer.putShort(e.code);
+            byteBuffer.putInt(e.value);
+        }
+        try {
+            IoBridge.write(
+                    sock.getFileDescriptor(), byteBuffer.array(), 0, byteBuffer.array().length);
+        } catch (IOException e) {
+            Log.d(TAG, "cannot send event", e);
+            return false;
+        }
+        return true;
+    }
+
+    private android.system.virtualizationservice.VirtualMachineConfig
+            createVirtualMachineConfigForAppFrom(
+                    VirtualMachineConfig vmConfig, IVirtualizationService service)
+                    throws RemoteException, IOException, VirtualMachineException {
+        VirtualMachineAppConfig appConfig = vmConfig.toVsConfig(mContext.getPackageManager());
+        appConfig.instanceImage = ParcelFileDescriptor.open(mInstanceFilePath, MODE_READ_WRITE);
+        appConfig.name = mName;
+        if (mInstanceIdPath != null) {
+            appConfig.instanceId = Files.readAllBytes(mInstanceIdPath.toPath());
+        } else {
+            // FEATURE_LLPVM_CHANGES is disabled, instance_id is not used.
+            appConfig.instanceId = new byte[64];
+        }
+        if (mEncryptedStoreFilePath != null) {
+            appConfig.encryptedStorageImage =
+                    ParcelFileDescriptor.open(mEncryptedStoreFilePath, MODE_READ_WRITE);
+        }
+
+        if (!vmConfig.getExtraApks().isEmpty()) {
+            // Extra APKs were specified directly, rather than via config file.
+            // We've already populated the file names for the extra APKs and IDSigs
+            // (via setupExtraApks). But we also need to open the APK files and add
+            // fds for them to the payload config.
+            // This isn't needed when the extra APKs are specified in a config file -
+            // then
+            // Virtualization Manager opens them itself.
+            List<ParcelFileDescriptor> extraApkFiles = new ArrayList<>(mExtraApks.size());
+            for (ExtraApkSpec extraApk : mExtraApks) {
+                try {
+                    extraApkFiles.add(ParcelFileDescriptor.open(extraApk.apk, MODE_READ_ONLY));
+                } catch (FileNotFoundException e) {
+                    throw new VirtualMachineException("Failed to open extra APK", e);
+                }
+            }
+            appConfig.payload.getPayloadConfig().extraApks = extraApkFiles;
+        }
+
+        try {
+            createIdSigsAndUpdateConfig(service, appConfig);
+        } catch (FileNotFoundException e) {
+            throw new VirtualMachineException("Failed to generate APK signature", e);
+        }
+        return android.system.virtualizationservice.VirtualMachineConfig.appConfig(appConfig);
+    }
+
+    /**
+     * Runs this virtual machine. The returning of this method however doesn't mean that the VM has
+     * actually started running or the OS has booted there. Such events can be notified by
+     * registering a callback using {@link #setCallback} before calling {@code run()}. There is no
+     * limit other than available memory that limits the number of virtual machines that can run at
+     * the same time.
+     *
+     * <p>NOTE: This method may block and should not be called on the main thread.
+     *
+     * @throws VirtualMachineException if the virtual machine is not stopped or could not be
+     *     started.
+     * @hide
+     */
+    @SystemApi
+    @WorkerThread
+    @RequiresPermission(MANAGE_VIRTUAL_MACHINE_PERMISSION)
+    public void run() throws VirtualMachineException {
+        synchronized (mLock) {
+            checkStopped();
+
+            try {
+                mIdsigFilePath.createNewFile();
+                for (ExtraApkSpec extraApk : mExtraApks) {
+                    extraApk.idsig.createNewFile();
+                }
+            } catch (IOException e) {
+                // If the file already exists, exception is not thrown.
+                throw new VirtualMachineException("Failed to create APK signature file", e);
+            }
+
+            IVirtualizationService service = mVirtualizationService.getBinder();
+
+            try {
+                if (mConnectVmConsole) {
+                    createPtyConsole();
+                }
+
+                if (mVmOutputCaptured) {
+                    createVmOutputPipes();
+                }
+
+                if (mVmConsoleInputSupported) {
+                    createVmInputPipes();
+                }
+
+                ParcelFileDescriptor consoleOutFd = null;
+                if (mConnectVmConsole && mVmOutputCaptured) {
+                    // If we are enabling output pipes AND the host console, then we tee the console
+                    // output to both.
+                    ParcelFileDescriptor[] pipe = ParcelFileDescriptor.createPipe();
+                    mTeeConsoleOutReader = pipe[0];
+                    mTeeConsoleOutWriter = pipe[1];
+                    consoleOutFd = mTeeConsoleOutWriter;
+                    TeeWorker tee =
+                            new TeeWorker(
+                                    mName + " console",
+                                    new FileInputStream(mTeeConsoleOutReader.getFileDescriptor()),
+                                    List.of(
+                                            new FileOutputStream(mPtyFd.getFileDescriptor()),
+                                            new FileOutputStream(
+                                                    mConsoleOutWriter.getFileDescriptor())));
+                    // If the VM is stopped then the tee worker thread would get an EOF or read()
+                    // error which would tear down itself.
+                    mConsoleExecutor.execute(tee);
+                } else if (mConnectVmConsole) {
+                    consoleOutFd = mPtyFd;
+                } else if (mVmOutputCaptured) {
+                    consoleOutFd = mConsoleOutWriter;
+                }
+                mInputEventExecutor = Executors.newSingleThreadExecutor();
+                mInputEventExecutor.execute(
+                        () -> {
+                            while (true) {
+                                try {
+                                    Pair<InputEventType, MotionEvent> event =
+                                            mInputEventQueue.take();
+                                    switch (event.first) {
+                                        case TOUCH:
+                                            sendMultiTouchEventInternal(event.second);
+                                            break;
+                                        case TRACKPAD:
+                                            sendTrackpadEventInternal(event.second);
+                                            break;
+                                        case MOUSE:
+                                            sendMouseEventInternal(event.second);
+                                            break;
+                                    }
+                                    event.second.recycle();
+                                } catch (Exception e) {
+                                    Log.e(TAG, e.toString());
+                                }
+                            }
+                        });
+                ParcelFileDescriptor consoleInFd = null;
+                if (mConnectVmConsole) {
+                    consoleInFd = mPtyFd;
+                } else if (mVmConsoleInputSupported) {
+                    consoleInFd = mConsoleInReader;
+                }
+
+                VirtualMachineConfig vmConfig = getConfig();
+                android.system.virtualizationservice.VirtualMachineConfig vmConfigParcel =
+                        vmConfig.getCustomImageConfig() != null
+                                ? createVirtualMachineConfigForRawFrom(vmConfig)
+                                : createVirtualMachineConfigForAppFrom(vmConfig, service);
+
+                mVirtualMachine =
+                        service.createVm(vmConfigParcel, consoleOutFd, consoleInFd, mLogWriter);
+                mVirtualMachine.registerCallback(new CallbackTranslator(service));
+                if (mMemoryManagementCallbacks != null) {
+                    mContext.registerComponentCallbacks(mMemoryManagementCallbacks);
+                }
+                if (mConnectVmConsole) {
+                    mVirtualMachine.setHostConsoleName(getHostConsoleName());
+                }
+                mVirtualMachine.start();
+            } catch (IOException e) {
+                throw new VirtualMachineException("failed to persist files", e);
+            } catch (IllegalStateException | ServiceSpecificException e) {
+                throw new VirtualMachineException(e);
+            } catch (RemoteException e) {
+                throw e.rethrowAsRuntimeException();
+            }
+        }
+    }
+
+    private void createIdSigsAndUpdateConfig(
+            IVirtualizationService service, VirtualMachineAppConfig appConfig)
+            throws RemoteException, FileNotFoundException {
+        // Fill the idsig file by hashing the apk
+        service.createOrUpdateIdsigFile(
+                appConfig.apk, ParcelFileDescriptor.open(mIdsigFilePath, MODE_READ_WRITE));
+
+        for (ExtraApkSpec extraApk : mExtraApks) {
+            service.createOrUpdateIdsigFile(
+                    ParcelFileDescriptor.open(extraApk.apk, MODE_READ_ONLY),
+                    ParcelFileDescriptor.open(extraApk.idsig, MODE_READ_WRITE));
+        }
+
+        // Re-open idsig files in read-only mode
+        appConfig.idsig = ParcelFileDescriptor.open(mIdsigFilePath, MODE_READ_ONLY);
+        List<ParcelFileDescriptor> extraIdsigs = new ArrayList<>();
+        for (ExtraApkSpec extraApk : mExtraApks) {
+            extraIdsigs.add(ParcelFileDescriptor.open(extraApk.idsig, MODE_READ_ONLY));
+        }
+        appConfig.extraIdsigs = extraIdsigs;
+    }
+
+    @GuardedBy("mLock")
+    private void createVmOutputPipes() throws VirtualMachineException {
+        try {
+            if (mConsoleOutReader == null || mConsoleOutWriter == null) {
+                ParcelFileDescriptor[] pipe = ParcelFileDescriptor.createPipe();
+                mConsoleOutReader = pipe[0];
+                mConsoleOutWriter = pipe[1];
+            }
+
+            if (mLogReader == null || mLogWriter == null) {
+                ParcelFileDescriptor[] pipe = ParcelFileDescriptor.createPipe();
+                mLogReader = pipe[0];
+                mLogWriter = pipe[1];
+            }
+        } catch (IOException e) {
+            throw new VirtualMachineException("Failed to create output stream for VM", e);
+        }
+    }
+
+    @GuardedBy("mLock")
+    private void createVmInputPipes() throws VirtualMachineException {
+        try {
+            if (mConsoleInReader == null || mConsoleInWriter == null) {
+                if (mConnectVmConsole) {
+                    // If we are enabling input pipes AND the host console, then we should just use
+                    // the host pty peer end as the console write end.
+                    createPtyConsole();
+                    mConsoleInReader = mPtyFd.dup();
+                    mConsoleInWriter = mPtsFd.dup();
+                } else {
+                    ParcelFileDescriptor[] pipe = ParcelFileDescriptor.createPipe();
+                    mConsoleInReader = pipe[0];
+                    mConsoleInWriter = pipe[1];
+                }
+            }
+        } catch (IOException e) {
+            throw new VirtualMachineException("Failed to create input stream for VM", e);
+        }
+    }
+
+    @FunctionalInterface
+    private static interface OpenPtyCallback {
+        public void apply(FileDescriptor mfd, FileDescriptor sfd, byte[] name);
+    }
+
+    // Opens a pty and set the master end to raw mode and O_NONBLOCK.
+    private static native void nativeOpenPtyRawNonblock(OpenPtyCallback resultCallback)
+            throws IOException;
+
+    @GuardedBy("mLock")
+    private void createPtyConsole() throws VirtualMachineException {
+        if (mPtyFd != null && mPtsFd != null) {
+            return;
+        }
+        List<FileDescriptor> fd = new ArrayList<>(2);
+        StringBuilder nameBuilder = new StringBuilder();
+        try {
+            try {
+                nativeOpenPtyRawNonblock(
+                        (FileDescriptor mfd, FileDescriptor sfd, byte[] ptsName) -> {
+                            fd.add(mfd);
+                            fd.add(sfd);
+                            nameBuilder.append(new String(ptsName, StandardCharsets.UTF_8));
+                        });
+            } catch (Exception e) {
+                fd.forEach(IoUtils::closeQuietly);
+                throw e;
+            }
+        } catch (IOException e) {
+            throw new VirtualMachineException(
+                    "Failed to create host console to connect to the VM console", e);
+        }
+        mPtyFd = new ParcelFileDescriptor(fd.get(0));
+        mPtsFd = new ParcelFileDescriptor(fd.get(1));
+        mPtsName = nameBuilder.toString();
+        Log.d(TAG, "Serial console device: " + mPtsName);
+    }
+
+    /**
+     * Returns the name of the peer end (ptsname) of the host console. The host console is only
+     * available if the {@link VirtualMachineConfig} specifies that a host console should
+     * {@linkplain VirtualMachineConfig#isConnectVmConsole connect} to the VM console.
+     *
+     * @throws VirtualMachineException if the host pseudoterminal could not be created, or
+     *     connecting to the VM console is not enabled.
+     * @hide
+     */
+    @NonNull
+    private String getHostConsoleName() throws VirtualMachineException {
+        if (!mConnectVmConsole) {
+            throw new VirtualMachineException("Host console is not enabled");
+        }
+        synchronized (mLock) {
+            createPtyConsole();
+            return mPtsName;
+        }
+    }
+
+    /**
+     * Returns the stream object representing the console output from the virtual machine. The
+     * console output is only available if the {@link VirtualMachineConfig} specifies that it should
+     * be {@linkplain VirtualMachineConfig#isVmOutputCaptured captured}.
+     *
+     * <p>If you turn on output capture, you must consume data from {@code getConsoleOutput} -
+     * because otherwise the code in the VM may get blocked when the pipe buffer fills up.
+     *
+     * <p>NOTE: This method may block and should not be called on the main thread.
+     *
+     * @throws VirtualMachineException if the stream could not be created, or capturing is turned
+     *     off.
+     * @hide
+     */
+    @SystemApi
+    @WorkerThread
+    @NonNull
+    public InputStream getConsoleOutput() throws VirtualMachineException {
+        if (!mVmOutputCaptured) {
+            throw new VirtualMachineException("Capturing vm outputs is turned off");
+        }
+        synchronized (mLock) {
+            createVmOutputPipes();
+            return new FileInputStream(mConsoleOutReader.getFileDescriptor());
+        }
+    }
+
+    /**
+     * Returns the stream object representing the console input to the virtual machine. The console
+     * input is only available if the {@link VirtualMachineConfig} specifies that it should be
+     * {@linkplain VirtualMachineConfig#isVmConsoleInputSupported supported}.
+     *
+     * <p>NOTE: This method may block and should not be called on the main thread.
+     *
+     * @throws VirtualMachineException if the stream could not be created, or console input is not
+     *     supported.
+     * @hide
+     */
+    @TestApi
+    @WorkerThread
+    @NonNull
+    public OutputStream getConsoleInput() throws VirtualMachineException {
+        if (!mVmConsoleInputSupported) {
+            throw new VirtualMachineException("VM console input is not supported");
+        }
+        synchronized (mLock) {
+            createVmInputPipes();
+            return new FileOutputStream(mConsoleInWriter.getFileDescriptor());
+        }
+    }
+
+    /**
+     * Returns the stream object representing the log output from the virtual machine. The log
+     * output is only available if the VirtualMachineConfig specifies that it should be {@linkplain
+     * VirtualMachineConfig#isVmOutputCaptured captured}.
+     *
+     * <p>If you turn on output capture, you must consume data from {@code getLogOutput} - because
+     * otherwise the code in the VM may get blocked when the pipe buffer fills up.
+     *
+     * <p>NOTE: This method may block and should not be called on the main thread.
+     *
+     * @throws VirtualMachineException if the stream could not be created, or capturing is turned
+     *     off.
+     * @hide
+     */
+    @SystemApi
+    @WorkerThread
+    @NonNull
+    public InputStream getLogOutput() throws VirtualMachineException {
+        if (!mVmOutputCaptured) {
+            throw new VirtualMachineException("Capturing vm outputs is turned off");
+        }
+        synchronized (mLock) {
+            createVmOutputPipes();
+            return new FileInputStream(mLogReader.getFileDescriptor());
+        }
+    }
+
+    /**
+     * Stops this virtual machine. Stopping a virtual machine is like pulling the plug on a real
+     * computer; the machine halts immediately. Software running on the virtual machine is not
+     * notified of the event. Writes to {@linkplain
+     * VirtualMachineConfig.Builder#setEncryptedStorageBytes encrypted storage} might not be
+     * persisted, and the instance might be left in an inconsistent state.
+     *
+     * <p>For a graceful shutdown, you could request the payload to call {@code exit()}, e.g. via a
+     * {@linkplain #connectToVsockServer binder request}, and wait for {@link
+     * VirtualMachineCallback#onPayloadFinished} to be called.
+     *
+     * <p>A stopped virtual machine can be re-started by calling {@link #run()}.
+     *
+     * <p>NOTE: This method may block and should not be called on the main thread.
+     *
+     * @throws VirtualMachineException if the virtual machine is not running or could not be
+     *     stopped.
+     * @hide
+     */
+    @SystemApi
+    @WorkerThread
+    public void stop() throws VirtualMachineException {
+        synchronized (mLock) {
+            if (mVirtualMachine == null) {
+                throw new VirtualMachineException("VM is not running");
+            }
+            try {
+                mVirtualMachine.stop();
+                dropVm();
+                if (mInputEventExecutor != null) {
+                    mInputEventExecutor.shutdownNow();
+                }
+            } catch (RemoteException e) {
+                throw e.rethrowAsRuntimeException();
+            } catch (ServiceSpecificException e) {
+                throw new VirtualMachineException(e);
+            }
+        }
+    }
+
+    /** @hide */
+    public void suspend() throws VirtualMachineException {
+        synchronized (mLock) {
+            if (mVirtualMachine == null) {
+                throw new VirtualMachineException("VM is not running");
+            }
+            try {
+                mVirtualMachine.suspend();
+            } catch (RemoteException e) {
+                throw e.rethrowAsRuntimeException();
+            } catch (ServiceSpecificException e) {
+                throw new VirtualMachineException(e);
+            }
+        }
+    }
+
+    /** @hide */
+    public void resume() throws VirtualMachineException {
+        synchronized (mLock) {
+            if (mVirtualMachine == null) {
+                throw new VirtualMachineException("VM is not running");
+            }
+            try {
+                mVirtualMachine.resume();
+            } catch (RemoteException e) {
+                throw e.rethrowAsRuntimeException();
+            } catch (ServiceSpecificException e) {
+                throw new VirtualMachineException(e);
+            }
+        }
+    }
+
+    /**
+     * Stops this virtual machine, if it is running.
+     *
+     * <p>NOTE: This method may block and should not be called on the main thread.
+     *
+     * @see #stop()
+     * @hide
+     */
+    @SystemApi
+    @WorkerThread
+    @Override
+    public void close() {
+        synchronized (mLock) {
+            if (mVirtualMachine == null) {
+                return;
+            }
+            try {
+                if (stateToStatus(mVirtualMachine.getState()) == STATUS_RUNNING) {
+                    mVirtualMachine.stop();
+                    dropVm();
+                }
+            } catch (RemoteException e) {
+                throw e.rethrowAsRuntimeException();
+            } catch (ServiceSpecificException e) {
+                // Deliberately ignored; this almost certainly means the VM exited just as
+                // we tried to stop it.
+                Log.i(TAG, "Ignoring error on close()", e);
+            }
+        }
+    }
+
+    private static void deleteRecursively(File dir) throws IOException {
+        // Note: This doesn't follow symlinks, which is important. Instead they are just deleted
+        // (and Files.delete deletes the link not the target).
+        Files.walkFileTree(
+                dir.toPath(),
+                new SimpleFileVisitor<>() {
+                    @Override
+                    public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
+                            throws IOException {
+                        Files.delete(file);
+                        return FileVisitResult.CONTINUE;
+                    }
+
+                    @Override
+                    public FileVisitResult postVisitDirectory(Path dir, IOException e)
+                            throws IOException {
+                        // Directory is deleted after we've visited (deleted) all its contents, so
+                        // it
+                        // should be empty by now.
+                        Files.delete(dir);
+                        return FileVisitResult.CONTINUE;
+                    }
+                });
+    }
+
+    /**
+     * Changes the config of this virtual machine to a new one. This can be used to adjust things
+     * like the number of CPU and size of the RAM, depending on the situation (e.g. the size of the
+     * application to run on the virtual machine, etc.)
+     *
+     * <p>The new config must be {@linkplain VirtualMachineConfig#isCompatibleWith compatible with}
+     * the existing config.
+     *
+     * <p>NOTE: This method may block and should not be called on the main thread.
+     *
+     * @return the old config
+     * @throws VirtualMachineException if the virtual machine is not stopped, or the new config is
+     *     incompatible.
+     * @hide
+     */
+    @SystemApi
+    @WorkerThread
+    @NonNull
+    public VirtualMachineConfig setConfig(@NonNull VirtualMachineConfig newConfig)
+            throws VirtualMachineException {
+        synchronized (mLock) {
+            VirtualMachineConfig oldConfig = mConfig;
+            if (!oldConfig.isCompatibleWith(newConfig)) {
+                throw new VirtualMachineException("incompatible config");
+            }
+            checkStopped();
+
+            if (oldConfig != newConfig) {
+                // Delete any existing file before recreating; that ensures any
+                // VirtualMachineDescriptor that refers to the old file does not see the new config.
+                mConfigFilePath.delete();
+                newConfig.serialize(mConfigFilePath);
+                mConfig = newConfig;
+            }
+            return oldConfig;
+        }
+    }
+
+    @Nullable
+    private static native IBinder nativeConnectToVsockServer(IBinder vmBinder, int port);
+
+    /**
+     * Connect to a VM's binder service via vsock and return the root IBinder object. Guest VMs are
+     * expected to set up vsock servers in their payload. After the host app receives the {@link
+     * VirtualMachineCallback#onPayloadReady}, it can use this method to establish a connection to
+     * the guest VM.
+     *
+     * <p>NOTE: This method may block and should not be called on the main thread.
+     *
+     * @throws VirtualMachineException if the virtual machine is not running or the connection
+     *     failed.
+     * @hide
+     */
+    @SystemApi
+    @WorkerThread
+    @NonNull
+    public IBinder connectToVsockServer(
+            @IntRange(from = MIN_VSOCK_PORT, to = MAX_VSOCK_PORT) long port)
+            throws VirtualMachineException {
+
+        synchronized (mLock) {
+            IBinder iBinder =
+                    nativeConnectToVsockServer(getRunningVm().asBinder(), validatePort(port));
+            if (iBinder == null) {
+                throw new VirtualMachineException("Failed to connect to vsock server");
+            }
+            return iBinder;
+        }
+    }
+
+    /**
+     * Opens a vsock connection to the VM on the given port.
+     *
+     * <p>The caller is responsible for closing the returned {@code ParcelFileDescriptor}.
+     *
+     * <p>NOTE: This method may block and should not be called on the main thread.
+     *
+     * @throws VirtualMachineException if connecting fails.
+     * @hide
+     */
+    @SystemApi
+    @WorkerThread
+    @NonNull
+    public ParcelFileDescriptor connectVsock(
+            @IntRange(from = MIN_VSOCK_PORT, to = MAX_VSOCK_PORT) long port)
+            throws VirtualMachineException {
+        synchronized (mLock) {
+            try {
+                return getRunningVm().connectVsock(validatePort(port));
+            } catch (RemoteException e) {
+                throw e.rethrowAsRuntimeException();
+            } catch (ServiceSpecificException e) {
+                throw new VirtualMachineException(e);
+            }
+        }
+    }
+
+    private int validatePort(long port) {
+        // Ports below 1024 are "privileged" (payload code can't bind to these), and port numbers
+        // are 32-bit unsigned numbers at the OS level, even though we pass them as 32-bit signed
+        // numbers internally.
+        if (port < MIN_VSOCK_PORT || port > MAX_VSOCK_PORT) {
+            throw new IllegalArgumentException("Bad port " + port);
+        }
+        return (int) port;
+    }
+
+    /**
+     * Returns the root directory where all files related to this {@link VirtualMachine} (e.g.
+     * {@code instance.img}, {@code apk.idsig}, etc) are stored.
+     *
+     * @hide
+     */
+    @TestApi
+    @NonNull
+    public File getRootDir() {
+        return mVmRootPath;
+    }
+
+    /**
+     * Enables the VM to request attestation in testing mode.
+     *
+     * <p>This function provisions a key pair for the VM attestation testing, a fake certificate
+     * will be associated to the fake key pair when the VM requests attestation in testing mode.
+     *
+     * <p>The provisioned key pair can only be used in subsequent calls to {@link
+     * AVmPayload_requestAttestationForTesting} within a running VM.
+     *
+     * @hide
+     */
+    @TestApi
+    @RequiresPermission(USE_CUSTOM_VIRTUAL_MACHINE_PERMISSION)
+    @FlaggedApi(Flags.FLAG_AVF_V_TEST_APIS)
+    public void enableTestAttestation() throws VirtualMachineException {
+        try {
+            mVirtualizationService.getBinder().enableTestAttestation();
+        } catch (RemoteException e) {
+            throw e.rethrowAsRuntimeException();
+        }
+    }
+
+    /**
+     * Captures the current state of the VM in a {@link VirtualMachineDescriptor} instance. The VM
+     * needs to be stopped to avoid inconsistency in its state representation.
+     *
+     * <p>The state of the VM is not actually copied until {@link
+     * VirtualMachineManager#importFromDescriptor} is called. It is recommended that the VM not be
+     * started until that operation is complete.
+     *
+     * <p>NOTE: This method may block and should not be called on the main thread.
+     *
+     * @return a {@link VirtualMachineDescriptor} instance that represents the VM's state.
+     * @throws VirtualMachineException if the virtual machine is not stopped, or the state could not
+     *     be captured.
+     * @hide
+     */
+    @SystemApi
+    @WorkerThread
+    @NonNull
+    public VirtualMachineDescriptor toDescriptor() throws VirtualMachineException {
+        synchronized (mLock) {
+            checkStopped();
+            try {
+                return new VirtualMachineDescriptor(
+                        ParcelFileDescriptor.open(mConfigFilePath, MODE_READ_ONLY),
+                        mInstanceIdPath != null
+                                ? ParcelFileDescriptor.open(mInstanceIdPath, MODE_READ_ONLY)
+                                : null,
+                        ParcelFileDescriptor.open(mInstanceFilePath, MODE_READ_ONLY),
+                        mEncryptedStoreFilePath != null
+                                ? ParcelFileDescriptor.open(mEncryptedStoreFilePath, MODE_READ_ONLY)
+                                : null);
+            } catch (IOException e) {
+                throw new VirtualMachineException(e);
+            }
+        }
+    }
+
+    @Override
+    public String toString() {
+        VirtualMachineConfig config = getConfig();
+        String payloadConfigPath = config.getPayloadConfigPath();
+        String payloadBinaryName = config.getPayloadBinaryName();
+
+        StringBuilder result = new StringBuilder();
+        result.append("VirtualMachine(").append("name:").append(getName()).append(", ");
+        if (payloadBinaryName != null) {
+            result.append("payload:").append(payloadBinaryName).append(", ");
+        }
+        if (payloadConfigPath != null) {
+            result.append("config:").append(payloadConfigPath).append(", ");
+        }
+        result.append("package: ").append(mPackageName).append(")");
+        return result.toString();
+    }
+
+    /**
+     * Reads the payload config inside the application, parses extra APK information, and then
+     * creates corresponding idsig file paths.
+     */
+    private static List<ExtraApkSpec> setupExtraApks(
+            @NonNull Context context, @NonNull VirtualMachineConfig config, @NonNull File vmDir)
+            throws VirtualMachineException {
+        String configPath = config.getPayloadConfigPath();
+        List<String> extraApks = config.getExtraApks();
+        if (configPath != null) {
+            return setupExtraApksFromConfigFile(context, vmDir, configPath);
+        } else if (!extraApks.isEmpty()) {
+            return setupExtraApksFromList(context, vmDir, extraApks);
+        } else {
+            return Collections.emptyList();
+        }
+    }
+
+    private static List<ExtraApkSpec> setupExtraApksFromConfigFile(
+            Context context, File vmDir, String configPath) throws VirtualMachineException {
+        try (ZipFile zipFile = new ZipFile(context.getPackageCodePath())) {
+            InputStream inputStream = zipFile.getInputStream(zipFile.getEntry(configPath));
+            List<String> apkList =
+                    parseExtraApkListFromPayloadConfig(
+                            new JsonReader(new InputStreamReader(inputStream)));
+
+            List<ExtraApkSpec> extraApks = new ArrayList<>(apkList.size());
+            for (int i = 0; i < apkList.size(); ++i) {
+                extraApks.add(
+                        new ExtraApkSpec(
+                                new File(apkList.get(i)),
+                                new File(vmDir, EXTRA_IDSIG_FILE_PREFIX + i)));
+            }
+
+            return extraApks;
+        } catch (IOException e) {
+            throw new VirtualMachineException("Couldn't parse extra apks from the vm config", e);
+        }
+    }
+
+    private static List<String> parseExtraApkListFromPayloadConfig(JsonReader reader)
+            throws VirtualMachineException {
+        /*
+         * JSON schema from packages/modules/Virtualization/microdroid/libs/libmicrodroid_payload_metadata/config/src/lib.rs:
+         *
+         * <p>{ "extra_apks": [ { "path": "/system/app/foo.apk", }, ... ], ... }
+         */
+        try {
+            List<String> apks = new ArrayList<>();
+
+            reader.beginObject();
+            while (reader.hasNext()) {
+                if (reader.nextName().equals("extra_apks")) {
+                    reader.beginArray();
+                    while (reader.hasNext()) {
+                        reader.beginObject();
+                        String name = reader.nextName();
+                        if (name.equals("path")) {
+                            apks.add(reader.nextString());
+                        } else {
+                            reader.skipValue();
+                        }
+                        reader.endObject();
+                    }
+                    reader.endArray();
+                } else {
+                    reader.skipValue();
+                }
+            }
+            reader.endObject();
+            return apks;
+        } catch (IOException e) {
+            throw new VirtualMachineException(e);
+        }
+    }
+
+    private static List<ExtraApkSpec> setupExtraApksFromList(
+            Context context, File vmDir, List<String> extraApkInfo) throws VirtualMachineException {
+        int count = extraApkInfo.size();
+        List<ExtraApkSpec> extraApks = new ArrayList<>(count);
+        for (int i = 0; i < count; i++) {
+            String packageName = extraApkInfo.get(i);
+            ApplicationInfo appInfo;
+            try {
+                appInfo =
+                        context.getPackageManager()
+                                .getApplicationInfo(
+                                        packageName, PackageManager.ApplicationInfoFlags.of(0));
+            } catch (PackageManager.NameNotFoundException e) {
+                throw new VirtualMachineException("Extra APK package not found", e);
+            }
+
+            extraApks.add(
+                    new ExtraApkSpec(
+                            new File(appInfo.sourceDir),
+                            new File(vmDir, EXTRA_IDSIG_FILE_PREFIX + i)));
+        }
+        return extraApks;
+    }
+
+    private void importInstanceIdFrom(@NonNull ParcelFileDescriptor instanceIdFd)
+            throws VirtualMachineException {
+        try (FileChannel idOutput = new FileOutputStream(mInstanceIdPath).getChannel();
+                FileChannel idInput = new AutoCloseInputStream(instanceIdFd).getChannel()) {
+            idOutput.transferFrom(idInput, /* position= */ 0, idInput.size());
+        } catch (IOException e) {
+            throw new VirtualMachineException("failed to copy instance_id", e);
+        }
+    }
+
+    private void importInstanceFrom(@NonNull ParcelFileDescriptor instanceFd)
+            throws VirtualMachineException {
+        try (FileChannel instance = new FileOutputStream(mInstanceFilePath).getChannel();
+                FileChannel instanceInput = new AutoCloseInputStream(instanceFd).getChannel()) {
+            instance.transferFrom(instanceInput, /* position= */ 0, instanceInput.size());
+        } catch (IOException e) {
+            throw new VirtualMachineException("failed to transfer instance image", e);
+        }
+    }
+
+    private void importEncryptedStoreFrom(@NonNull ParcelFileDescriptor encryptedStoreFd)
+            throws VirtualMachineException {
+        try (FileChannel storeOutput = new FileOutputStream(mEncryptedStoreFilePath).getChannel();
+                FileChannel storeInput = new AutoCloseInputStream(encryptedStoreFd).getChannel()) {
+            storeOutput.transferFrom(storeInput, /* position= */ 0, storeInput.size());
+        } catch (IOException e) {
+            throw new VirtualMachineException("failed to transfer encryptedstore image", e);
+        }
+    }
+
+    /** Map the raw AIDL (& binder) callbacks to what the client expects. */
+    private class CallbackTranslator extends IVirtualMachineCallback.Stub {
+        private final IVirtualizationService mService;
+        private final DeathRecipient mDeathRecipient;
+
+        // The VM should only be observed to die once
+        private final AtomicBoolean mOnDiedCalled = new AtomicBoolean(false);
+
+        public CallbackTranslator(IVirtualizationService service) throws RemoteException {
+            this.mService = service;
+            this.mDeathRecipient = () -> reportStopped(STOP_REASON_VIRTUALIZATION_SERVICE_DIED);
+            service.asBinder().linkToDeath(mDeathRecipient, 0);
+        }
+
+        @Override
+        public void onPayloadStarted(int cid) {
+            executeCallback((cb) -> cb.onPayloadStarted(VirtualMachine.this));
+        }
+
+        @Override
+        public void onPayloadReady(int cid) {
+            executeCallback((cb) -> cb.onPayloadReady(VirtualMachine.this));
+        }
+
+        @Override
+        public void onPayloadFinished(int cid, int exitCode) {
+            executeCallback((cb) -> cb.onPayloadFinished(VirtualMachine.this, exitCode));
+        }
+
+        @Override
+        public void onError(int cid, int errorCode, String message) {
+            int translatedError = getTranslatedError(errorCode);
+            executeCallback((cb) -> cb.onError(VirtualMachine.this, translatedError, message));
+        }
+
+        @Override
+        public void onDied(int cid, int reason) {
+            int translatedReason = getTranslatedReason(reason);
+            reportStopped(translatedReason);
+            mService.asBinder().unlinkToDeath(mDeathRecipient, 0);
+        }
+
+        private void reportStopped(@VirtualMachineCallback.StopReason int reason) {
+            if (mOnDiedCalled.compareAndSet(false, true)) {
+                executeCallback((cb) -> cb.onStopped(VirtualMachine.this, reason));
+            }
+        }
+
+        @VirtualMachineCallback.ErrorCode
+        private int getTranslatedError(int reason) {
+            switch (reason) {
+                case ErrorCode.PAYLOAD_VERIFICATION_FAILED:
+                    return ERROR_PAYLOAD_VERIFICATION_FAILED;
+                case ErrorCode.PAYLOAD_CHANGED:
+                    return ERROR_PAYLOAD_CHANGED;
+                case ErrorCode.PAYLOAD_INVALID_CONFIG:
+                    return ERROR_PAYLOAD_INVALID_CONFIG;
+                default:
+                    return ERROR_UNKNOWN;
+            }
+        }
+
+        @VirtualMachineCallback.StopReason
+        private int getTranslatedReason(int reason) {
+            switch (reason) {
+                case DeathReason.INFRASTRUCTURE_ERROR:
+                    return STOP_REASON_INFRASTRUCTURE_ERROR;
+                case DeathReason.KILLED:
+                    return STOP_REASON_KILLED;
+                case DeathReason.SHUTDOWN:
+                    return STOP_REASON_SHUTDOWN;
+                case DeathReason.START_FAILED:
+                    return STOP_REASON_START_FAILED;
+                case DeathReason.REBOOT:
+                    return STOP_REASON_REBOOT;
+                case DeathReason.CRASH:
+                    return STOP_REASON_CRASH;
+                case DeathReason.PVM_FIRMWARE_PUBLIC_KEY_MISMATCH:
+                    return STOP_REASON_PVM_FIRMWARE_PUBLIC_KEY_MISMATCH;
+                case DeathReason.PVM_FIRMWARE_INSTANCE_IMAGE_CHANGED:
+                    return STOP_REASON_PVM_FIRMWARE_INSTANCE_IMAGE_CHANGED;
+                case DeathReason.MICRODROID_FAILED_TO_CONNECT_TO_VIRTUALIZATION_SERVICE:
+                    return STOP_REASON_MICRODROID_FAILED_TO_CONNECT_TO_VIRTUALIZATION_SERVICE;
+                case DeathReason.MICRODROID_PAYLOAD_HAS_CHANGED:
+                    return STOP_REASON_MICRODROID_PAYLOAD_HAS_CHANGED;
+                case DeathReason.MICRODROID_PAYLOAD_VERIFICATION_FAILED:
+                    return STOP_REASON_MICRODROID_PAYLOAD_VERIFICATION_FAILED;
+                case DeathReason.MICRODROID_INVALID_PAYLOAD_CONFIG:
+                    return STOP_REASON_MICRODROID_INVALID_PAYLOAD_CONFIG;
+                case DeathReason.MICRODROID_UNKNOWN_RUNTIME_ERROR:
+                    return STOP_REASON_MICRODROID_UNKNOWN_RUNTIME_ERROR;
+                case DeathReason.HANGUP:
+                    return STOP_REASON_HANGUP;
+                default:
+                    return STOP_REASON_UNKNOWN;
+            }
+        }
+    }
+
+    /**
+     * Duplicates {@code InputStream} data to multiple {@code OutputStream}. Like the "tee" command.
+     *
+     * <p>Supports non-blocking writes to the output streams by ignoring EAGAIN error.
+     */
+    private static class TeeWorker implements Runnable {
+        private final String mName;
+        private final InputStream mIn;
+        private final List<OutputStream> mOuts;
+
+        TeeWorker(String name, InputStream in, Collection<OutputStream> outs) {
+            mName = name;
+            mIn = in;
+            mOuts = new ArrayList<>(outs);
+        }
+
+        @Override
+        public void run() {
+            byte[] buffer = new byte[2048];
+            try {
+                while (!Thread.interrupted()) {
+                    int len = mIn.read(buffer);
+                    if (len < 0) {
+                        break;
+                    }
+                    for (OutputStream out : mOuts) {
+                        try {
+                            out.write(buffer, 0, len);
+                        } catch (IOException e) {
+                            // EAGAIN is expected because the file description has O_NONBLOCK flag.
+                            if (!isErrnoError(e, OsConstants.EAGAIN)) {
+                                throw e;
+                            }
+                        }
+                    }
+                }
+            } catch (Exception e) {
+                Log.e(TAG, "Tee " + mName, e);
+            }
+        }
+
+        private static ErrnoException asErrnoException(Throwable e) {
+            if (e instanceof ErrnoException) {
+                return (ErrnoException) e;
+            } else if (e instanceof IOException) {
+                // Try to unwrap ErrnoException#rethrowAsIOException()
+                return asErrnoException(e.getCause());
+            }
+            return null;
+        }
+
+        private static boolean isErrnoError(Exception e, int expectedValue) {
+            ErrnoException errno = asErrnoException(e);
+            return errno != null && errno.errno == expectedValue;
+        }
+    }
+}
diff --git a/libs/framework-virtualization/src/android/system/virtualmachine/VirtualMachineCallback.java b/libs/framework-virtualization/src/android/system/virtualmachine/VirtualMachineCallback.java
new file mode 100644
index 0000000..b077826
--- /dev/null
+++ b/libs/framework-virtualization/src/android/system/virtualmachine/VirtualMachineCallback.java
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.system.virtualmachine;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.SuppressLint;
+import android.annotation.SystemApi;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Callback interface to get notified with the events from the virtual machine. The methods are
+ * executed on a binder thread. Implementations can make blocking calls in the methods.
+ *
+ * @hide
+ */
+@SystemApi
+@SuppressLint("CallbackInterface") // Guidance has changed, lint is out of date (b/245552641)
+public interface VirtualMachineCallback {
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(
+            prefix = "ERROR_",
+            value = {
+                ERROR_UNKNOWN,
+                ERROR_PAYLOAD_VERIFICATION_FAILED,
+                ERROR_PAYLOAD_CHANGED,
+                ERROR_PAYLOAD_INVALID_CONFIG
+            })
+    @interface ErrorCode {}
+
+    /** Error code for all other errors not listed below. */
+    int ERROR_UNKNOWN = 0;
+
+    /**
+     * Error code indicating that the payload can't be verified due to various reasons (e.g invalid
+     * merkle tree, invalid formats, etc).
+     */
+    int ERROR_PAYLOAD_VERIFICATION_FAILED = 1;
+
+    /** Error code indicating that the payload is verified, but has changed since the last boot. */
+    int ERROR_PAYLOAD_CHANGED = 2;
+
+    /** Error code indicating that the payload config is invalid. */
+    int ERROR_PAYLOAD_INVALID_CONFIG = 3;
+
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(
+            prefix = "STOP_REASON_",
+            value = {
+                STOP_REASON_VIRTUALIZATION_SERVICE_DIED,
+                STOP_REASON_INFRASTRUCTURE_ERROR,
+                STOP_REASON_KILLED,
+                STOP_REASON_UNKNOWN,
+                STOP_REASON_SHUTDOWN,
+                STOP_REASON_START_FAILED,
+                STOP_REASON_REBOOT,
+                STOP_REASON_CRASH,
+                STOP_REASON_PVM_FIRMWARE_PUBLIC_KEY_MISMATCH,
+                STOP_REASON_PVM_FIRMWARE_INSTANCE_IMAGE_CHANGED,
+                STOP_REASON_BOOTLOADER_PUBLIC_KEY_MISMATCH,
+                STOP_REASON_BOOTLOADER_INSTANCE_IMAGE_CHANGED,
+                STOP_REASON_MICRODROID_FAILED_TO_CONNECT_TO_VIRTUALIZATION_SERVICE,
+                STOP_REASON_MICRODROID_PAYLOAD_HAS_CHANGED,
+                STOP_REASON_MICRODROID_PAYLOAD_VERIFICATION_FAILED,
+                STOP_REASON_MICRODROID_INVALID_PAYLOAD_CONFIG,
+                STOP_REASON_MICRODROID_UNKNOWN_RUNTIME_ERROR,
+                STOP_REASON_HANGUP,
+            })
+    @interface StopReason {}
+
+    /** The virtualization service itself died, taking the VM down with it. */
+    //  This is a negative number to avoid conflicting with the other death reasons which match
+    //  the ones in the AIDL interface.
+    int STOP_REASON_VIRTUALIZATION_SERVICE_DIED = -1;
+
+    /** There was an error waiting for the VM. */
+    int STOP_REASON_INFRASTRUCTURE_ERROR = 0;
+
+    /** The VM was killed. */
+    int STOP_REASON_KILLED = 1;
+
+    /** The VM died for an unknown reason. */
+    int STOP_REASON_UNKNOWN = 2;
+
+    /** The VM requested to shut down. */
+    int STOP_REASON_SHUTDOWN = 3;
+
+    /** crosvm had an error starting the VM. */
+    int STOP_REASON_START_FAILED = 4;
+
+    /** The VM requested to reboot, possibly as the result of a kernel panic. */
+    int STOP_REASON_REBOOT = 5;
+
+    /** The VM or crosvm crashed. */
+    int STOP_REASON_CRASH = 6;
+
+    /** The pVM firmware failed to verify the VM because the public key doesn't match. */
+    int STOP_REASON_PVM_FIRMWARE_PUBLIC_KEY_MISMATCH = 7;
+
+    /** The pVM firmware failed to verify the VM because the instance image changed. */
+    int STOP_REASON_PVM_FIRMWARE_INSTANCE_IMAGE_CHANGED = 8;
+
+    /** The bootloader failed to verify the VM because the public key doesn't match. */
+    int STOP_REASON_BOOTLOADER_PUBLIC_KEY_MISMATCH = 9;
+
+    /** The bootloader failed to verify the VM because the instance image changed. */
+    int STOP_REASON_BOOTLOADER_INSTANCE_IMAGE_CHANGED = 10;
+
+    /** The microdroid failed to connect to VirtualizationService's RPC server. */
+    int STOP_REASON_MICRODROID_FAILED_TO_CONNECT_TO_VIRTUALIZATION_SERVICE = 11;
+
+    /** The payload for microdroid is changed. */
+    int STOP_REASON_MICRODROID_PAYLOAD_HAS_CHANGED = 12;
+
+    /** The microdroid failed to verify given payload APK. */
+    int STOP_REASON_MICRODROID_PAYLOAD_VERIFICATION_FAILED = 13;
+
+    /** The VM config for microdroid is invalid (e.g. missing tasks). */
+    int STOP_REASON_MICRODROID_INVALID_PAYLOAD_CONFIG = 14;
+
+    /** There was a runtime error while running microdroid manager. */
+    int STOP_REASON_MICRODROID_UNKNOWN_RUNTIME_ERROR = 15;
+
+    /** The VM killed due to hangup */
+    int STOP_REASON_HANGUP = 16;
+
+    /** Called when the payload starts in the VM. */
+    void onPayloadStarted(@NonNull VirtualMachine vm);
+
+    /**
+     * Called when the payload in the VM is ready to serve. See {@link
+     * VirtualMachine#connectToVsockServer}.
+     */
+    void onPayloadReady(@NonNull VirtualMachine vm);
+
+    /** Called when the payload has finished in the VM. */
+    void onPayloadFinished(@NonNull VirtualMachine vm, int exitCode);
+
+    /** Called when an error occurs in the VM. */
+    void onError(@NonNull VirtualMachine vm, @ErrorCode int errorCode, @NonNull String message);
+
+    /** Called when the VM has stopped. */
+    void onStopped(@NonNull VirtualMachine vm, @StopReason int reason);
+}
diff --git a/libs/framework-virtualization/src/android/system/virtualmachine/VirtualMachineConfig.java b/libs/framework-virtualization/src/android/system/virtualmachine/VirtualMachineConfig.java
new file mode 100644
index 0000000..7ae4a55
--- /dev/null
+++ b/libs/framework-virtualization/src/android/system/virtualmachine/VirtualMachineConfig.java
@@ -0,0 +1,1289 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.system.virtualmachine;
+
+import static android.os.ParcelFileDescriptor.AutoCloseInputStream;
+import static android.os.ParcelFileDescriptor.MODE_READ_ONLY;
+import static android.os.ParcelFileDescriptor.MODE_READ_WRITE;
+
+import static java.util.Objects.requireNonNull;
+
+import android.annotation.FlaggedApi;
+import android.annotation.IntDef;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
+import android.annotation.StringDef;
+import android.annotation.SystemApi;
+import android.annotation.TestApi;
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.os.Build;
+import android.os.ParcelFileDescriptor;
+import android.os.PersistableBundle;
+import android.sysprop.HypervisorProperties;
+import android.system.virtualizationservice.DiskImage;
+import android.system.virtualizationservice.Partition;
+import android.system.virtualizationservice.VirtualMachineAppConfig;
+import android.system.virtualizationservice.VirtualMachinePayloadConfig;
+import android.system.virtualizationservice.VirtualMachineRawConfig;
+import android.text.TextUtils;
+import android.util.Log;
+
+import com.android.system.virtualmachine.flags.Flags;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.zip.ZipFile;
+
+/**
+ * Represents a configuration of a virtual machine. A configuration consists of hardware
+ * configurations like the number of CPUs and the size of RAM, and software configurations like the
+ * payload to run on the virtual machine.
+ *
+ * @hide
+ */
+@SystemApi
+public final class VirtualMachineConfig {
+    private static final String TAG = "VirtualMachineConfig";
+
+    private static String[] EMPTY_STRING_ARRAY = {};
+    private static final String U_BOOT_PREBUILT_PATH = "/apex/com.android.virt/etc/u-boot.bin";
+
+    // These define the schema of the config file persisted on disk.
+    // Please bump up the version number when adding a new key.
+    private static final int VERSION = 10;
+    private static final String KEY_VERSION = "version";
+    private static final String KEY_PACKAGENAME = "packageName";
+    private static final String KEY_APKPATH = "apkPath";
+    private static final String KEY_PAYLOADCONFIGPATH = "payloadConfigPath";
+    private static final String KEY_CUSTOMIMAGECONFIG = "customImageConfig";
+    private static final String KEY_PAYLOADBINARYNAME = "payloadBinaryPath";
+    private static final String KEY_DEBUGLEVEL = "debugLevel";
+    private static final String KEY_PROTECTED_VM = "protectedVm";
+    private static final String KEY_MEMORY_BYTES = "memoryBytes";
+    private static final String KEY_CPU_TOPOLOGY = "cpuTopology";
+    private static final String KEY_CONSOLE_INPUT_DEVICE = "consoleInputDevice";
+    private static final String KEY_ENCRYPTED_STORAGE_BYTES = "encryptedStorageBytes";
+    private static final String KEY_VM_OUTPUT_CAPTURED = "vmOutputCaptured";
+    private static final String KEY_VM_CONSOLE_INPUT_SUPPORTED = "vmConsoleInputSupported";
+    private static final String KEY_CONNECT_VM_CONSOLE = "connectVmConsole";
+    private static final String KEY_VENDOR_DISK_IMAGE_PATH = "vendorDiskImagePath";
+    private static final String KEY_OS = "os";
+    private static final String KEY_EXTRA_APKS = "extraApks";
+    private static final String KEY_SHOULD_BOOST_UCLAMP = "shouldBoostUclamp";
+    private static final String KEY_SHOULD_USE_HUGEPAGES = "shouldUseHugepages";
+
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(
+            prefix = "DEBUG_LEVEL_",
+            value = {DEBUG_LEVEL_NONE, DEBUG_LEVEL_FULL})
+    public @interface DebugLevel {}
+
+    /**
+     * Not debuggable at all. No log is exported from the VM. Debugger can't be attached to the app
+     * process running in the VM. This is the default level.
+     *
+     * @hide
+     */
+    @SystemApi public static final int DEBUG_LEVEL_NONE = 0;
+
+    /**
+     * Fully debuggable. All logs (both logcat and kernel message) are exported. All processes
+     * running in the VM can be attached to the debugger. Rooting is possible.
+     *
+     * @hide
+     */
+    @SystemApi public static final int DEBUG_LEVEL_FULL = 1;
+
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(
+            prefix = "CPU_TOPOLOGY_",
+            value = {
+                CPU_TOPOLOGY_ONE_CPU,
+                CPU_TOPOLOGY_MATCH_HOST,
+            })
+    public @interface CpuTopology {}
+
+    /**
+     * Run VM with 1 vCPU. This is the default option, usually the fastest to boot and consuming the
+     * least amount of resources. Typically the best option for small or ephemeral workloads.
+     *
+     * @hide
+     */
+    @SystemApi public static final int CPU_TOPOLOGY_ONE_CPU = 0;
+
+    /**
+     * Run VM with vCPU topology matching the physical CPU topology of the host. Usually takes
+     * longer to boot and consumes more resources compared to a single vCPU. Typically a good option
+     * for long-running workloads that benefit from parallel execution.
+     *
+     * @hide
+     */
+    @SystemApi public static final int CPU_TOPOLOGY_MATCH_HOST = 1;
+
+    /** Name of a package whose primary APK contains the VM payload. */
+    @Nullable private final String mPackageName;
+
+    /** Absolute path to the APK file containing the VM payload. */
+    @Nullable private final String mApkPath;
+
+    private final List<String> mExtraApks;
+
+    @DebugLevel private final int mDebugLevel;
+
+    /** Whether to run the VM in protected mode, so the host can't access its memory. */
+    private final boolean mProtectedVm;
+
+    /**
+     * The amount of RAM to give the VM, in bytes. If this is 0 or negative the default will be
+     * used.
+     */
+    private final long mMemoryBytes;
+
+    /** CPU topology configuration of the VM. */
+    @CpuTopology private final int mCpuTopology;
+
+    /** The serial device for VM console input. */
+    @Nullable private final String mConsoleInputDevice;
+
+    /** Path within the APK to the payload config file that defines software aspects of the VM. */
+    @Nullable private final String mPayloadConfigPath;
+
+    /** Name of the payload binary file within the APK that will be executed within the VM. */
+    @Nullable private final String mPayloadBinaryName;
+
+    /** The custom image config file to launch the custom VM. */
+    @Nullable private final VirtualMachineCustomImageConfig mCustomImageConfig;
+
+    /** The size of storage in bytes. 0 indicates that encryptedStorage is not required */
+    private final long mEncryptedStorageBytes;
+
+    /** Whether the app can read console and log output. */
+    private final boolean mVmOutputCaptured;
+
+    /** Whether the app can write console input to the VM */
+    private final boolean mVmConsoleInputSupported;
+
+    /** Whether to connect the VM console to a host console. */
+    private final boolean mConnectVmConsole;
+
+    @Nullable private final File mVendorDiskImage;
+
+    /** OS name of the VM using payload binaries. */
+    @NonNull @OsName private final String mOs;
+
+    private final boolean mShouldBoostUclamp;
+
+    private final boolean mShouldUseHugepages;
+
+    @Retention(RetentionPolicy.SOURCE)
+    @StringDef(
+            prefix = "MICRODROID",
+            value = {MICRODROID})
+    private @interface OsName {}
+
+    /**
+     * OS name of microdroid using microdroid kernel.
+     *
+     * @see Builder#setOs
+     * @hide
+     */
+    @TestApi
+    @FlaggedApi(Flags.FLAG_AVF_V_TEST_APIS)
+    @OsName
+    public static final String MICRODROID = "microdroid";
+
+    private VirtualMachineConfig(
+            @Nullable String packageName,
+            @Nullable String apkPath,
+            List<String> extraApks,
+            @Nullable String payloadConfigPath,
+            @Nullable String payloadBinaryName,
+            @Nullable VirtualMachineCustomImageConfig customImageConfig,
+            @DebugLevel int debugLevel,
+            boolean protectedVm,
+            long memoryBytes,
+            @CpuTopology int cpuTopology,
+            @Nullable String consoleInputDevice,
+            long encryptedStorageBytes,
+            boolean vmOutputCaptured,
+            boolean vmConsoleInputSupported,
+            boolean connectVmConsole,
+            @Nullable File vendorDiskImage,
+            @NonNull @OsName String os,
+            boolean shouldBoostUclamp,
+            boolean shouldUseHugepages) {
+        // This is only called from Builder.build(); the builder handles parameter validation.
+        mPackageName = packageName;
+        mApkPath = apkPath;
+        mExtraApks =
+                extraApks.isEmpty()
+                        ? Collections.emptyList()
+                        : Collections.unmodifiableList(
+                                Arrays.asList(extraApks.toArray(new String[0])));
+        mPayloadConfigPath = payloadConfigPath;
+        mPayloadBinaryName = payloadBinaryName;
+        mCustomImageConfig = customImageConfig;
+        mDebugLevel = debugLevel;
+        mProtectedVm = protectedVm;
+        mMemoryBytes = memoryBytes;
+        mCpuTopology = cpuTopology;
+        mConsoleInputDevice = consoleInputDevice;
+        mEncryptedStorageBytes = encryptedStorageBytes;
+        mVmOutputCaptured = vmOutputCaptured;
+        mVmConsoleInputSupported = vmConsoleInputSupported;
+        mConnectVmConsole = connectVmConsole;
+        mVendorDiskImage = vendorDiskImage;
+        mOs = os;
+        mShouldBoostUclamp = shouldBoostUclamp;
+        mShouldUseHugepages = shouldUseHugepages;
+    }
+
+    /** Loads a config from a file. */
+    @NonNull
+    static VirtualMachineConfig from(@NonNull File file) throws VirtualMachineException {
+        try (FileInputStream input = new FileInputStream(file)) {
+            return fromInputStream(input);
+        } catch (IOException e) {
+            throw new VirtualMachineException("Failed to read VM config from file", e);
+        }
+    }
+
+    /** Loads a config from a {@link ParcelFileDescriptor}. */
+    @NonNull
+    static VirtualMachineConfig from(@NonNull ParcelFileDescriptor fd)
+            throws VirtualMachineException {
+        try (AutoCloseInputStream input = new AutoCloseInputStream(fd)) {
+            return fromInputStream(input);
+        } catch (IOException e) {
+            throw new VirtualMachineException("failed to read VM config from file descriptor", e);
+        }
+    }
+
+    /** Loads a config from a stream, for example a file. */
+    @NonNull
+    private static VirtualMachineConfig fromInputStream(@NonNull InputStream input)
+            throws IOException, VirtualMachineException {
+        PersistableBundle b = PersistableBundle.readFromStream(input);
+        try {
+            return fromPersistableBundle(b);
+        } catch (NullPointerException | IllegalArgumentException | IllegalStateException e) {
+            throw new VirtualMachineException("Persisted VM config is invalid", e);
+        }
+    }
+
+    @NonNull
+    private static VirtualMachineConfig fromPersistableBundle(PersistableBundle b) {
+        int version = b.getInt(KEY_VERSION);
+        if (version > VERSION) {
+            throw new IllegalArgumentException(
+                    "Version " + version + " too high; current is " + VERSION);
+        }
+
+        String packageName = b.getString(KEY_PACKAGENAME);
+        Builder builder = new Builder(packageName);
+
+        String apkPath = b.getString(KEY_APKPATH);
+        if (apkPath != null) {
+            builder.setApkPath(apkPath);
+        }
+
+        String payloadConfigPath = b.getString(KEY_PAYLOADCONFIGPATH);
+        String payloadBinaryName = b.getString(KEY_PAYLOADBINARYNAME);
+        PersistableBundle customImageConfigBundle = b.getPersistableBundle(KEY_CUSTOMIMAGECONFIG);
+        if (customImageConfigBundle != null) {
+            builder.setCustomImageConfig(
+                    VirtualMachineCustomImageConfig.from(customImageConfigBundle));
+        } else if (payloadConfigPath != null) {
+            builder.setPayloadConfigPath(payloadConfigPath);
+        } else {
+            builder.setPayloadBinaryName(payloadBinaryName);
+        }
+
+        @DebugLevel int debugLevel = b.getInt(KEY_DEBUGLEVEL);
+        if (debugLevel != DEBUG_LEVEL_NONE && debugLevel != DEBUG_LEVEL_FULL) {
+            throw new IllegalArgumentException("Invalid debugLevel: " + debugLevel);
+        }
+        builder.setDebugLevel(debugLevel);
+        builder.setProtectedVm(b.getBoolean(KEY_PROTECTED_VM));
+        long memoryBytes = b.getLong(KEY_MEMORY_BYTES);
+        if (memoryBytes != 0) {
+            builder.setMemoryBytes(memoryBytes);
+        }
+        builder.setCpuTopology(b.getInt(KEY_CPU_TOPOLOGY));
+        String consoleInputDevice = b.getString(KEY_CONSOLE_INPUT_DEVICE);
+        if (consoleInputDevice != null) {
+            builder.setConsoleInputDevice(consoleInputDevice);
+        }
+        long encryptedStorageBytes = b.getLong(KEY_ENCRYPTED_STORAGE_BYTES);
+        if (encryptedStorageBytes != 0) {
+            builder.setEncryptedStorageBytes(encryptedStorageBytes);
+        }
+        builder.setVmOutputCaptured(b.getBoolean(KEY_VM_OUTPUT_CAPTURED));
+        builder.setVmConsoleInputSupported(b.getBoolean(KEY_VM_CONSOLE_INPUT_SUPPORTED));
+        builder.setConnectVmConsole(b.getBoolean(KEY_CONNECT_VM_CONSOLE));
+
+        String vendorDiskImagePath = b.getString(KEY_VENDOR_DISK_IMAGE_PATH);
+        if (vendorDiskImagePath != null) {
+            builder.setVendorDiskImage(new File(vendorDiskImagePath));
+        }
+
+        builder.setOs(b.getString(KEY_OS));
+
+        String[] extraApks = b.getStringArray(KEY_EXTRA_APKS);
+        if (extraApks != null) {
+            for (String extraApk : extraApks) {
+                builder.addExtraApk(extraApk);
+            }
+        }
+
+        builder.setShouldBoostUclamp(b.getBoolean(KEY_SHOULD_BOOST_UCLAMP));
+        builder.setShouldUseHugepages(b.getBoolean(KEY_SHOULD_USE_HUGEPAGES));
+
+        return builder.build();
+    }
+
+    /** Persists this config to a file. */
+    void serialize(@NonNull File file) throws VirtualMachineException {
+        try (FileOutputStream output = new FileOutputStream(file)) {
+            serializeOutputStream(output);
+        } catch (IOException e) {
+            throw new VirtualMachineException("failed to write VM config", e);
+        }
+    }
+
+    /** Persists this config to a stream, for example a file. */
+    private void serializeOutputStream(@NonNull OutputStream output) throws IOException {
+        PersistableBundle b = new PersistableBundle();
+        b.putInt(KEY_VERSION, VERSION);
+        if (mPackageName != null) {
+            b.putString(KEY_PACKAGENAME, mPackageName);
+        }
+        if (mApkPath != null) {
+            b.putString(KEY_APKPATH, mApkPath);
+        }
+        b.putString(KEY_PAYLOADCONFIGPATH, mPayloadConfigPath);
+        b.putString(KEY_PAYLOADBINARYNAME, mPayloadBinaryName);
+        if (mCustomImageConfig != null) {
+            b.putPersistableBundle(KEY_CUSTOMIMAGECONFIG, mCustomImageConfig.toPersistableBundle());
+        }
+        b.putInt(KEY_DEBUGLEVEL, mDebugLevel);
+        b.putBoolean(KEY_PROTECTED_VM, mProtectedVm);
+        b.putInt(KEY_CPU_TOPOLOGY, mCpuTopology);
+        if (mConsoleInputDevice != null) {
+            b.putString(KEY_CONSOLE_INPUT_DEVICE, mConsoleInputDevice);
+        }
+        if (mMemoryBytes > 0) {
+            b.putLong(KEY_MEMORY_BYTES, mMemoryBytes);
+        }
+        if (mEncryptedStorageBytes > 0) {
+            b.putLong(KEY_ENCRYPTED_STORAGE_BYTES, mEncryptedStorageBytes);
+        }
+        b.putBoolean(KEY_VM_OUTPUT_CAPTURED, mVmOutputCaptured);
+        b.putBoolean(KEY_VM_CONSOLE_INPUT_SUPPORTED, mVmConsoleInputSupported);
+        b.putBoolean(KEY_CONNECT_VM_CONSOLE, mConnectVmConsole);
+        if (mVendorDiskImage != null) {
+            b.putString(KEY_VENDOR_DISK_IMAGE_PATH, mVendorDiskImage.getAbsolutePath());
+        }
+        b.putString(KEY_OS, mOs);
+        if (!mExtraApks.isEmpty()) {
+            String[] extraApks = mExtraApks.toArray(new String[0]);
+            b.putStringArray(KEY_EXTRA_APKS, extraApks);
+        }
+        b.putBoolean(KEY_SHOULD_BOOST_UCLAMP, mShouldBoostUclamp);
+        b.putBoolean(KEY_SHOULD_USE_HUGEPAGES, mShouldUseHugepages);
+        b.writeToStream(output);
+    }
+
+    /**
+     * Returns the absolute path of the APK which should contain the binary payload that will
+     * execute within the VM. Returns null if no specific path has been set.
+     *
+     * @hide
+     */
+    @SystemApi
+    @Nullable
+    public String getApkPath() {
+        return mApkPath;
+    }
+
+    /**
+     * Returns the package names of any extra APKs that have been requested for the VM. They are
+     * returned in the order in which they were added via {@link Builder#addExtraApk}.
+     *
+     * @hide
+     */
+    @TestApi
+    @FlaggedApi(Flags.FLAG_AVF_V_TEST_APIS)
+    @NonNull
+    public List<String> getExtraApks() {
+        return mExtraApks;
+    }
+
+    /**
+     * Returns the path within the APK to the payload config file that defines software aspects of
+     * the VM.
+     *
+     * @hide
+     */
+    @TestApi
+    @Nullable
+    public String getPayloadConfigPath() {
+        return mPayloadConfigPath;
+    }
+
+    /**
+     * Returns the custom image config to launch the custom VM.
+     *
+     * @hide
+     */
+    @Nullable
+    public VirtualMachineCustomImageConfig getCustomImageConfig() {
+        return mCustomImageConfig;
+    }
+
+    /**
+     * Returns the name of the payload binary file, in the {@code lib/<ABI>} directory of the APK,
+     * that will be executed within the VM.
+     *
+     * @hide
+     */
+    @SystemApi
+    @Nullable
+    public String getPayloadBinaryName() {
+        return mPayloadBinaryName;
+    }
+
+    /**
+     * Returns the debug level for the VM.
+     *
+     * @hide
+     */
+    @SystemApi
+    @DebugLevel
+    public int getDebugLevel() {
+        return mDebugLevel;
+    }
+
+    /**
+     * Returns whether the VM's memory will be protected from the host.
+     *
+     * @hide
+     */
+    @SystemApi
+    public boolean isProtectedVm() {
+        return mProtectedVm;
+    }
+
+    /**
+     * Returns the amount of RAM that will be made available to the VM, or 0 if the default size
+     * will be used.
+     *
+     * @hide
+     */
+    @SystemApi
+    @IntRange(from = 0)
+    public long getMemoryBytes() {
+        return mMemoryBytes;
+    }
+
+    /**
+     * Returns the CPU topology configuration of the VM.
+     *
+     * @hide
+     */
+    @SystemApi
+    @CpuTopology
+    public int getCpuTopology() {
+        return mCpuTopology;
+    }
+
+    /**
+     * Returns whether encrypted storage is enabled or not.
+     *
+     * @hide
+     */
+    @SystemApi
+    public boolean isEncryptedStorageEnabled() {
+        return mEncryptedStorageBytes > 0;
+    }
+
+    /**
+     * Returns the size of encrypted storage (in bytes) available in the VM, or 0 if encrypted
+     * storage is not enabled
+     *
+     * @hide
+     */
+    @SystemApi
+    @IntRange(from = 0)
+    public long getEncryptedStorageBytes() {
+        return mEncryptedStorageBytes;
+    }
+
+    /**
+     * Returns whether the app can read the VM console or log output. If not, the VM output is
+     * automatically forwarded to the host logcat.
+     *
+     * @see Builder#setVmOutputCaptured
+     * @hide
+     */
+    @SystemApi
+    public boolean isVmOutputCaptured() {
+        return mVmOutputCaptured;
+    }
+
+    /**
+     * Returns whether the app can write to the VM console.
+     *
+     * @see Builder#setVmConsoleInputSupported
+     * @hide
+     */
+    @TestApi
+    public boolean isVmConsoleInputSupported() {
+        return mVmConsoleInputSupported;
+    }
+
+    /**
+     * Returns whether to connect the VM console to a host console.
+     *
+     * @see Builder#setConnectVmConsole
+     * @hide
+     */
+    public boolean isConnectVmConsole() {
+        return mConnectVmConsole;
+    }
+
+    /**
+     * Returns the OS of the VM.
+     *
+     * @see Builder#setOs
+     * @hide
+     */
+    @TestApi
+    @FlaggedApi(Flags.FLAG_AVF_V_TEST_APIS)
+    @NonNull
+    @OsName
+    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
+     * that would alter the identity of the VM (e.g. using a different payload or changing the debug
+     * mode) are considered incompatible.
+     *
+     * @see VirtualMachine#setConfig
+     * @hide
+     */
+    @SystemApi
+    public boolean isCompatibleWith(@NonNull VirtualMachineConfig other) {
+        if (this == other) {
+            return true;
+        }
+        return this.mDebugLevel == other.mDebugLevel
+                && this.mProtectedVm == other.mProtectedVm
+                && this.mEncryptedStorageBytes == other.mEncryptedStorageBytes
+                && this.mVmOutputCaptured == other.mVmOutputCaptured
+                && this.mVmConsoleInputSupported == other.mVmConsoleInputSupported
+                && this.mConnectVmConsole == other.mConnectVmConsole
+                && this.mConsoleInputDevice == other.mConsoleInputDevice
+                && (this.mVendorDiskImage == null) == (other.mVendorDiskImage == null)
+                && Objects.equals(this.mPayloadConfigPath, other.mPayloadConfigPath)
+                && Objects.equals(this.mPayloadBinaryName, other.mPayloadBinaryName)
+                && Objects.equals(this.mPackageName, other.mPackageName)
+                && Objects.equals(this.mOs, other.mOs)
+                && Objects.equals(this.mExtraApks, other.mExtraApks);
+    }
+
+    private ParcelFileDescriptor openOrNull(File file, int mode) {
+        try {
+            return ParcelFileDescriptor.open(file, mode);
+        } catch (FileNotFoundException e) {
+            Log.d(TAG, "cannot open", e);
+            return null;
+        }
+    }
+
+    VirtualMachineRawConfig toVsRawConfig() throws IllegalStateException, IOException {
+        VirtualMachineRawConfig config = new VirtualMachineRawConfig();
+        VirtualMachineCustomImageConfig customImageConfig = getCustomImageConfig();
+        requireNonNull(customImageConfig);
+        config.name = Optional.ofNullable(customImageConfig.getName()).orElse("");
+        config.instanceId = new byte[64];
+        config.kernel =
+                Optional.ofNullable(customImageConfig.getKernelPath())
+                        .map(
+                                (path) -> {
+                                    try {
+                                        return ParcelFileDescriptor.open(
+                                                new File(path), MODE_READ_ONLY);
+                                    } catch (FileNotFoundException e) {
+                                        throw new RuntimeException(e);
+                                    }
+                                })
+                        .orElse(null);
+
+        config.initrd =
+                Optional.ofNullable(customImageConfig.getInitrdPath())
+                        .map((path) -> openOrNull(new File(path), MODE_READ_ONLY))
+                        .orElse(null);
+        config.bootloader =
+                Optional.ofNullable(customImageConfig.getBootloaderPath())
+                        .map((path) -> openOrNull(new File(path), MODE_READ_ONLY))
+                        .orElse(null);
+
+        if (config.kernel == null && config.bootloader == null) {
+            config.bootloader = openOrNull(new File(U_BOOT_PREBUILT_PATH), MODE_READ_ONLY);
+        }
+
+        config.params =
+                Optional.ofNullable(customImageConfig.getParams())
+                        .map((params) -> TextUtils.join(" ", params))
+                        .orElse("");
+        config.disks =
+                new DiskImage
+                        [Optional.ofNullable(customImageConfig.getDisks())
+                                .map(arr -> arr.length)
+                                .orElse(0)];
+        for (int i = 0; i < config.disks.length; i++) {
+            config.disks[i] = new DiskImage();
+            config.disks[i].writable = customImageConfig.getDisks()[i].isWritable();
+            String diskImagePath = customImageConfig.getDisks()[i].getImagePath();
+            if (diskImagePath != null) {
+                config.disks[i].image =
+                        ParcelFileDescriptor.open(
+                                new File(diskImagePath),
+                                config.disks[i].writable ? MODE_READ_WRITE : MODE_READ_ONLY);
+            }
+
+            List<Partition> partitions = new ArrayList<>();
+            for (VirtualMachineCustomImageConfig.Partition p :
+                    customImageConfig.getDisks()[i].getPartitions()) {
+                Partition part = new Partition();
+                part.label = p.name;
+                part.image =
+                        ParcelFileDescriptor.open(
+                                new File(p.imagePath),
+                                p.writable ? MODE_READ_WRITE : MODE_READ_ONLY);
+                part.writable = p.writable;
+                part.guid = TextUtils.isEmpty(p.guid) ? null : p.guid;
+                partitions.add(part);
+            }
+            config.disks[i].partitions = partitions.toArray(new Partition[0]);
+        }
+
+        config.displayConfig =
+                Optional.ofNullable(customImageConfig.getDisplayConfig())
+                        .map(dc -> dc.toParcelable())
+                        .orElse(null);
+        config.gpuConfig =
+                Optional.ofNullable(customImageConfig.getGpuConfig())
+                        .map(dc -> dc.toParcelable())
+                        .orElse(null);
+        config.protectedVm = this.mProtectedVm;
+        config.memoryMib = bytesToMebiBytes(mMemoryBytes);
+        config.cpuTopology = (byte) this.mCpuTopology;
+        config.consoleInputDevice = mConsoleInputDevice;
+        config.devices = EMPTY_STRING_ARRAY;
+        config.platformVersion = "~1.0";
+        config.audioConfig =
+                Optional.ofNullable(customImageConfig.getAudioConfig())
+                        .map(ac -> ac.toParcelable())
+                        .orElse(null);
+        return config;
+    }
+
+    /**
+     * Converts this config object into the parcelable type used when creating a VM via the
+     * virtualization service. Notice that the files are not passed as paths, but as file
+     * descriptors because the service doesn't accept paths as it might not have permission to open
+     * app-owned files and that could be abused to run a VM with software that the calling
+     * application doesn't own.
+     */
+    VirtualMachineAppConfig toVsConfig(@NonNull PackageManager packageManager)
+            throws VirtualMachineException {
+        VirtualMachineAppConfig vsConfig = new VirtualMachineAppConfig();
+
+        String apkPath = (mApkPath != null) ? mApkPath : findPayloadApk(packageManager);
+
+        try {
+            vsConfig.apk = ParcelFileDescriptor.open(new File(apkPath), MODE_READ_ONLY);
+        } catch (FileNotFoundException e) {
+            throw new VirtualMachineException("Failed to open APK", e);
+        }
+        if (mPayloadBinaryName != null) {
+            VirtualMachinePayloadConfig payloadConfig = new VirtualMachinePayloadConfig();
+            payloadConfig.payloadBinaryName = mPayloadBinaryName;
+            payloadConfig.extraApks = Collections.emptyList();
+            vsConfig.payload = VirtualMachineAppConfig.Payload.payloadConfig(payloadConfig);
+        } else {
+            vsConfig.payload = VirtualMachineAppConfig.Payload.configPath(mPayloadConfigPath);
+        }
+        vsConfig.osName = mOs;
+        switch (mDebugLevel) {
+            case DEBUG_LEVEL_FULL:
+                vsConfig.debugLevel = VirtualMachineAppConfig.DebugLevel.FULL;
+                break;
+            default:
+                vsConfig.debugLevel = VirtualMachineAppConfig.DebugLevel.NONE;
+                break;
+        }
+        vsConfig.protectedVm = mProtectedVm;
+        vsConfig.memoryMib = bytesToMebiBytes(mMemoryBytes);
+        switch (mCpuTopology) {
+            case CPU_TOPOLOGY_MATCH_HOST:
+                vsConfig.cpuTopology = android.system.virtualizationservice.CpuTopology.MATCH_HOST;
+                break;
+            default:
+                vsConfig.cpuTopology = android.system.virtualizationservice.CpuTopology.ONE_CPU;
+                break;
+        }
+
+        if (mVendorDiskImage != null) {
+            VirtualMachineAppConfig.CustomConfig customConfig =
+                    new VirtualMachineAppConfig.CustomConfig();
+            customConfig.devices = EMPTY_STRING_ARRAY;
+            try {
+                customConfig.vendorImage =
+                        ParcelFileDescriptor.open(mVendorDiskImage, MODE_READ_ONLY);
+            } catch (FileNotFoundException e) {
+                throw new VirtualMachineException(
+                        "Failed to open vendor disk image " + mVendorDiskImage.getAbsolutePath(),
+                        e);
+            }
+            vsConfig.customConfig = customConfig;
+        }
+
+        vsConfig.boostUclamp = mShouldBoostUclamp;
+        vsConfig.hugePages = mShouldUseHugepages;
+
+        return vsConfig;
+    }
+
+    private String findPayloadApk(PackageManager packageManager) throws VirtualMachineException {
+        ApplicationInfo appInfo;
+        try {
+            appInfo =
+                    packageManager.getApplicationInfo(
+                            mPackageName, PackageManager.ApplicationInfoFlags.of(0));
+        } catch (PackageManager.NameNotFoundException e) {
+            throw new VirtualMachineException("Package not found", e);
+        }
+
+        String[] splitApkPaths = appInfo.splitSourceDirs;
+        String[] abis = Build.SUPPORTED_64_BIT_ABIS;
+
+        // If there are split APKs, and we know the payload binary name, see if we can find a
+        // split APK containing the binary.
+        if (mPayloadBinaryName != null && splitApkPaths != null && abis.length != 0) {
+            String[] libraryNames = new String[abis.length];
+            for (int i = 0; i < abis.length; i++) {
+                libraryNames[i] = "lib/" + abis[i] + "/" + mPayloadBinaryName;
+            }
+
+            for (String path : splitApkPaths) {
+                try (ZipFile zip = new ZipFile(path)) {
+                    for (String name : libraryNames) {
+                        if (zip.getEntry(name) != null) {
+                            Log.i(TAG, "Found payload in " + path);
+                            return path;
+                        }
+                    }
+                } catch (IOException e) {
+                    Log.w(TAG, "Failed to scan split APK: " + path, e);
+                }
+            }
+        }
+
+        // This really is the path to the APK, not a directory.
+        return appInfo.sourceDir;
+    }
+
+    private int bytesToMebiBytes(long mMemoryBytes) {
+        long oneMebi = 1024 * 1024;
+        // We can't express requests for more than 2 exabytes, but then they're not going to succeed
+        // anyway.
+        if (mMemoryBytes > (Integer.MAX_VALUE - 1) * oneMebi) {
+            return Integer.MAX_VALUE;
+        }
+        return (int) ((mMemoryBytes + oneMebi - 1) / oneMebi);
+    }
+
+    /**
+     * A builder used to create a {@link VirtualMachineConfig}.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final class Builder {
+        @OsName private final String DEFAULT_OS = MICRODROID;
+
+        @Nullable private final String mPackageName;
+        @Nullable private String mApkPath;
+        private final List<String> mExtraApks = new ArrayList<>();
+        @Nullable private String mPayloadConfigPath;
+        @Nullable private VirtualMachineCustomImageConfig mCustomImageConfig;
+        @Nullable private String mPayloadBinaryName;
+        @DebugLevel private int mDebugLevel = DEBUG_LEVEL_NONE;
+        private boolean mProtectedVm;
+        private boolean mProtectedVmSet;
+        private long mMemoryBytes;
+        @CpuTopology private int mCpuTopology = CPU_TOPOLOGY_ONE_CPU;
+        @Nullable private String mConsoleInputDevice;
+        private long mEncryptedStorageBytes;
+        private boolean mVmOutputCaptured = false;
+        private boolean mVmConsoleInputSupported = false;
+        private boolean mConnectVmConsole = false;
+        @Nullable private File mVendorDiskImage;
+        @NonNull @OsName private String mOs = DEFAULT_OS;
+        private boolean mShouldBoostUclamp = false;
+        private boolean mShouldUseHugepages = false;
+
+        /**
+         * Creates a builder for the given context.
+         *
+         * @hide
+         */
+        @SystemApi
+        public Builder(@NonNull Context context) {
+            mPackageName = requireNonNull(context, "context must not be null").getPackageName();
+        }
+
+        /**
+         * Creates a builder for a specific package. If packageName is null, {@link #setApkPath}
+         * must be called to specify the APK containing the payload.
+         */
+        private Builder(@Nullable String packageName) {
+            mPackageName = packageName;
+        }
+
+        /**
+         * Builds an immutable {@link VirtualMachineConfig}
+         *
+         * @hide
+         */
+        @SystemApi
+        @NonNull
+        public VirtualMachineConfig build() {
+            String apkPath = null;
+            String packageName = null;
+
+            if (mApkPath != null) {
+                apkPath = mApkPath;
+            } else if (mPackageName != null) {
+                packageName = mPackageName;
+            } else {
+                // This should never happen, unless we're deserializing a bad config
+                throw new IllegalStateException("apkPath or packageName must be specified");
+            }
+            if (mCustomImageConfig != null) {
+                if (mPayloadBinaryName != null || mPayloadConfigPath != null) {
+                    throw new IllegalStateException(
+                            "setCustomImageConfig and (setPayloadBinaryName or"
+                                    + " setPayloadConfigPath) may not both be called");
+                }
+            } else if (mPayloadBinaryName == null) {
+                if (mPayloadConfigPath == null) {
+                    throw new IllegalStateException("setPayloadBinaryName must be called");
+                }
+                if (!mExtraApks.isEmpty()) {
+                    throw new IllegalStateException(
+                            "setPayloadConfigPath and addExtraApk may not both be called");
+                }
+            } else {
+                if (mPayloadConfigPath != null) {
+                    throw new IllegalStateException(
+                            "setPayloadBinaryName and setPayloadConfigPath may not both be called");
+                }
+            }
+
+            if (!mProtectedVmSet) {
+                throw new IllegalStateException("setProtectedVm must be called explicitly");
+            }
+
+            if (mVmOutputCaptured && mDebugLevel != DEBUG_LEVEL_FULL) {
+                throw new IllegalStateException("debug level must be FULL to capture output");
+            }
+
+            if (mVmConsoleInputSupported && mDebugLevel != DEBUG_LEVEL_FULL) {
+                throw new IllegalStateException("debug level must be FULL to use console input");
+            }
+
+            if (mConnectVmConsole && mDebugLevel != DEBUG_LEVEL_FULL) {
+                throw new IllegalStateException(
+                        "debug level must be FULL to connect to the console");
+            }
+
+            return new VirtualMachineConfig(
+                    packageName,
+                    apkPath,
+                    mExtraApks,
+                    mPayloadConfigPath,
+                    mPayloadBinaryName,
+                    mCustomImageConfig,
+                    mDebugLevel,
+                    mProtectedVm,
+                    mMemoryBytes,
+                    mCpuTopology,
+                    mConsoleInputDevice,
+                    mEncryptedStorageBytes,
+                    mVmOutputCaptured,
+                    mVmConsoleInputSupported,
+                    mConnectVmConsole,
+                    mVendorDiskImage,
+                    mOs,
+                    mShouldBoostUclamp,
+                    mShouldUseHugepages);
+        }
+
+        /**
+         * Sets the absolute path of the APK containing the binary payload that will execute within
+         * the VM. If not set explicitly, defaults to the split APK containing the payload, if there
+         * is one, and otherwise the primary APK of the context.
+         *
+         * @hide
+         */
+        @SystemApi
+        @NonNull
+        public Builder setApkPath(@NonNull String apkPath) {
+            requireNonNull(apkPath, "apkPath must not be null");
+            if (!apkPath.startsWith("/")) {
+                throw new IllegalArgumentException("APK path must be an absolute path");
+            }
+            mApkPath = apkPath;
+            return this;
+        }
+
+        /**
+         * Specify the package name of an extra APK to be included in the VM. Each extra APK is
+         * mounted, in unzipped form, inside the VM, allowing access to the code and/or data within
+         * it. The VM entry point must be in the main APK.
+         *
+         * @hide
+         */
+        @TestApi
+        @FlaggedApi(Flags.FLAG_AVF_V_TEST_APIS)
+        @NonNull
+        public Builder addExtraApk(@NonNull String packageName) {
+            mExtraApks.add(requireNonNull(packageName, "extra APK package name must not be null"));
+            return this;
+        }
+
+        /**
+         * Sets the path within the APK to the payload config file that defines software aspects of
+         * the VM. The file is a JSON file; see
+         * packages/modules/Virtualization/libs/libmicrodroid_payload_metadata/config/src/lib.rs for
+         * the format.
+         *
+         * @hide
+         */
+        @RequiresPermission(VirtualMachine.USE_CUSTOM_VIRTUAL_MACHINE_PERMISSION)
+        @TestApi
+        @NonNull
+        public Builder setPayloadConfigPath(@NonNull String payloadConfigPath) {
+            mPayloadConfigPath =
+                    requireNonNull(payloadConfigPath, "payloadConfigPath must not be null");
+            return this;
+        }
+
+        /**
+         * Sets the custom config file to launch the custom VM.
+         *
+         * @hide
+         */
+        @RequiresPermission(VirtualMachine.USE_CUSTOM_VIRTUAL_MACHINE_PERMISSION)
+        @NonNull
+        public Builder setCustomImageConfig(
+                @NonNull VirtualMachineCustomImageConfig customImageConfig) {
+            this.mCustomImageConfig = customImageConfig;
+            return this;
+        }
+
+        /**
+         * Sets the name of the payload binary file that will be executed within the VM, e.g.
+         * "payload.so". The file must reside in the {@code lib/<ABI>} directory of the APK.
+         *
+         * <p>Note that VMs only support 64-bit code, even if the owning app is running as a 32-bit
+         * process.
+         *
+         * @hide
+         */
+        @SystemApi
+        @NonNull
+        public Builder setPayloadBinaryName(@NonNull String payloadBinaryName) {
+            requireNonNull(payloadBinaryName, "payloadBinaryName must not be null");
+            if (payloadBinaryName.contains(File.separator)) {
+                throw new IllegalArgumentException(
+                        "Invalid binary file name: " + payloadBinaryName);
+            }
+            mPayloadBinaryName = payloadBinaryName;
+            return this;
+        }
+
+        /**
+         * Sets the debug level. Defaults to {@link #DEBUG_LEVEL_NONE}.
+         *
+         * <p>If {@link #DEBUG_LEVEL_FULL} is set then logs from inside the VM are exported to the
+         * host and adb connections from the host are possible. This is convenient for debugging but
+         * may compromise the integrity of the VM - including bypassing the protections offered by a
+         * {@linkplain #setProtectedVm protected VM}.
+         *
+         * <p>Note that it isn't possible to {@linkplain #isCompatibleWith change} the debug level
+         * of a VM instance; debug and non-debug VMs always have different secrets.
+         *
+         * @hide
+         */
+        @SystemApi
+        @NonNull
+        public Builder setDebugLevel(@DebugLevel int debugLevel) {
+            if (debugLevel != DEBUG_LEVEL_NONE && debugLevel != DEBUG_LEVEL_FULL) {
+                throw new IllegalArgumentException("Invalid debugLevel: " + debugLevel);
+            }
+            mDebugLevel = debugLevel;
+            return this;
+        }
+
+        /**
+         * Sets whether to protect the VM memory from the host. No default is provided, this must be
+         * set explicitly.
+         *
+         * <p>Note that if debugging is {@linkplain #setDebugLevel enabled} for a protected VM, the
+         * VM is not truly protected - direct memory access by the host is prevented, but e.g. the
+         * debugger can be used to access the VM's internals.
+         *
+         * <p>It isn't possible to {@linkplain #isCompatibleWith change} the protected status of a
+         * VM instance; protected and non-protected VMs always have different secrets.
+         *
+         * @see VirtualMachineManager#getCapabilities
+         * @hide
+         */
+        @SystemApi
+        @NonNull
+        public Builder setProtectedVm(boolean protectedVm) {
+            if (protectedVm) {
+                if (!HypervisorProperties.hypervisor_protected_vm_supported().orElse(false)) {
+                    throw new UnsupportedOperationException(
+                            "Protected VMs are not supported on this device.");
+                }
+            } else {
+                if (!HypervisorProperties.hypervisor_vm_supported().orElse(false)) {
+                    throw new UnsupportedOperationException(
+                            "Non-protected VMs are not supported on this device.");
+                }
+            }
+            mProtectedVm = protectedVm;
+            mProtectedVmSet = true;
+            return this;
+        }
+
+        /**
+         * Sets the amount of RAM to give the VM, in bytes. If not explicitly set then a default
+         * size will be used.
+         *
+         * @hide
+         */
+        @SystemApi
+        @NonNull
+        public Builder setMemoryBytes(@IntRange(from = 1) long memoryBytes) {
+            if (memoryBytes <= 0) {
+                throw new IllegalArgumentException("Memory size must be positive");
+            }
+            mMemoryBytes = memoryBytes;
+            return this;
+        }
+
+        /**
+         * Sets the CPU topology configuration of the VM. Defaults to {@link #CPU_TOPOLOGY_ONE_CPU}.
+         *
+         * <p>This determines how many virtual CPUs will be created, and their performance and
+         * scheduling characteristics, such as affinity masks. Topology also has an effect on memory
+         * usage as each vCPU requires additional memory to keep its state.
+         *
+         * @hide
+         */
+        @SystemApi
+        @NonNull
+        public Builder setCpuTopology(@CpuTopology int cpuTopology) {
+            if (cpuTopology != CPU_TOPOLOGY_ONE_CPU && cpuTopology != CPU_TOPOLOGY_MATCH_HOST) {
+                throw new IllegalArgumentException("Invalid cpuTopology: " + cpuTopology);
+            }
+            mCpuTopology = cpuTopology;
+            return this;
+        }
+
+        /**
+         * Sets the serial device for VM console input.
+         *
+         * @see android.system.virtualizationservice.ConsoleInputDevice
+         * @hide
+         */
+        public Builder setConsoleInputDevice(@Nullable String consoleInputDevice) {
+            mConsoleInputDevice = consoleInputDevice;
+            return this;
+        }
+
+        /**
+         * Sets the size (in bytes) of encrypted storage available to the VM. If not set, no
+         * encrypted storage is provided.
+         *
+         * <p>The storage is encrypted with a key deterministically derived from the VM identity
+         *
+         * <p>The encrypted storage is persistent across VM reboots as well as device reboots. The
+         * backing file (containing encrypted data) is stored in the app's private data directory.
+         *
+         * <p>Note - There is no integrity guarantee or rollback protection on the storage in case
+         * the encrypted data is modified.
+         *
+         * <p>Deleting the VM will delete the encrypted data - there is no way to recover that data.
+         *
+         * @hide
+         */
+        @SystemApi
+        @NonNull
+        public Builder setEncryptedStorageBytes(@IntRange(from = 1) long encryptedStorageBytes) {
+            if (encryptedStorageBytes <= 0) {
+                throw new IllegalArgumentException("Encrypted Storage size must be positive");
+            }
+            mEncryptedStorageBytes = encryptedStorageBytes;
+            return this;
+        }
+
+        /**
+         * Sets whether to allow the app to read the VM outputs (console / log). Default is {@code
+         * false}.
+         *
+         * <p>By default, console and log outputs of a {@linkplain #setDebugLevel debuggable} VM are
+         * automatically forwarded to the host logcat. Setting this as {@code true} will allow the
+         * app to directly read {@linkplain VirtualMachine#getConsoleOutput console output} and
+         * {@linkplain VirtualMachine#getLogOutput log output}, instead of forwarding them to the
+         * host logcat.
+         *
+         * <p>If you turn on output capture, you must consume data from {@link
+         * VirtualMachine#getConsoleOutput} and {@link VirtualMachine#getLogOutput} - because
+         * otherwise the code in the VM may get blocked when the pipe buffer fills up.
+         *
+         * <p>The {@linkplain #setDebugLevel debug level} must be {@link #DEBUG_LEVEL_FULL} to be
+         * set as true.
+         *
+         * @hide
+         */
+        @SystemApi
+        @NonNull
+        public Builder setVmOutputCaptured(boolean captured) {
+            mVmOutputCaptured = captured;
+            return this;
+        }
+
+        /**
+         * Sets whether to allow the app to write to the VM console. Default is {@code false}.
+         *
+         * <p>Setting this as {@code true} will allow the app to directly write into {@linkplain
+         * VirtualMachine#getConsoleInput console input}.
+         *
+         * <p>The {@linkplain #setDebugLevel debug level} must be {@link #DEBUG_LEVEL_FULL} to be
+         * set as true.
+         *
+         * @hide
+         */
+        @TestApi
+        @NonNull
+        public Builder setVmConsoleInputSupported(boolean supported) {
+            mVmConsoleInputSupported = supported;
+            return this;
+        }
+
+        /**
+         * Sets whether to connect the VM console to a host console. Default is {@code false}.
+         *
+         * <p>Setting this as {@code true} will allow the shell to directly communicate with the VM
+         * console through the connected host console.
+         *
+         * <p>The {@linkplain #setDebugLevel debug level} must be {@link #DEBUG_LEVEL_FULL} to be
+         * set as true.
+         *
+         * @hide
+         */
+        @NonNull
+        public Builder setConnectVmConsole(boolean supported) {
+            mConnectVmConsole = supported;
+            return this;
+        }
+
+        /**
+         * Sets the path to the disk image with vendor-specific modules.
+         *
+         * @hide
+         */
+        @TestApi
+        @FlaggedApi(Flags.FLAG_AVF_V_TEST_APIS)
+        @RequiresPermission(VirtualMachine.USE_CUSTOM_VIRTUAL_MACHINE_PERMISSION)
+        @NonNull
+        public Builder setVendorDiskImage(@NonNull File vendorDiskImage) {
+            mVendorDiskImage =
+                    requireNonNull(vendorDiskImage, "vendor disk image must not be null");
+            return this;
+        }
+
+        /**
+         * Sets an OS for the VM. Defaults to {@code "microdroid"}.
+         *
+         * <p>See {@link VirtualMachineManager#getSupportedOSList} for available OS names.
+         *
+         * @hide
+         */
+        @TestApi
+        @FlaggedApi(Flags.FLAG_AVF_V_TEST_APIS)
+        @RequiresPermission(VirtualMachine.USE_CUSTOM_VIRTUAL_MACHINE_PERMISSION)
+        @NonNull
+        public Builder setOs(@NonNull @OsName String os) {
+            mOs = requireNonNull(os, "os must not be null");
+            return this;
+        }
+
+        /** @hide */
+        public Builder setShouldBoostUclamp(boolean shouldBoostUclamp) {
+            mShouldBoostUclamp = shouldBoostUclamp;
+            return this;
+        }
+
+        /** @hide */
+        public Builder setShouldUseHugepages(boolean shouldUseHugepages) {
+            mShouldUseHugepages = shouldUseHugepages;
+            return this;
+        }
+    }
+}
diff --git a/libs/framework-virtualization/src/android/system/virtualmachine/VirtualMachineCustomImageConfig.java b/libs/framework-virtualization/src/android/system/virtualmachine/VirtualMachineCustomImageConfig.java
new file mode 100644
index 0000000..37dc8fa
--- /dev/null
+++ b/libs/framework-virtualization/src/android/system/virtualmachine/VirtualMachineCustomImageConfig.java
@@ -0,0 +1,913 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.system.virtualmachine;
+
+import android.annotation.Nullable;
+import android.os.PersistableBundle;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+
+/** @hide */
+public class VirtualMachineCustomImageConfig {
+    private static final String KEY_NAME = "name";
+    private static final String KEY_KERNEL = "kernel";
+    private static final String KEY_INITRD = "initrd";
+    private static final String KEY_BOOTLOADER = "bootloader";
+    private static final String KEY_PARAMS = "params";
+    private static final String KEY_DISK_WRITABLES = "disk_writables";
+    private static final String KEY_DISK_IMAGES = "disk_images";
+    private static final String KEY_PARTITION_LABELS = "partition_labels_";
+    private static final String KEY_PARTITION_IMAGES = "partition_images_";
+    private static final String KEY_PARTITION_WRITABLES = "partition_writables_";
+    private static final String KEY_PARTITION_GUIDS = "partition_guids_";
+    private static final String KEY_DISPLAY_CONFIG = "display_config";
+    private static final String KEY_TOUCH = "touch";
+    private static final String KEY_KEYBOARD = "keyboard";
+    private static final String KEY_MOUSE = "mouse";
+    private static final String KEY_SWITCHES = "switches";
+    private static final String KEY_NETWORK = "network";
+    private static final String KEY_GPU = "gpu";
+    private static final String KEY_AUDIO_CONFIG = "audio_config";
+    private static final String KEY_TRACKPAD = "trackpad";
+    private static final String KEY_AUTO_MEMORY_BALLOON = "auto_memory_balloon";
+
+    @Nullable private final String name;
+    @Nullable private final String kernelPath;
+    @Nullable private final String initrdPath;
+    @Nullable private final String bootloaderPath;
+    @Nullable private final String[] params;
+    @Nullable private final Disk[] disks;
+    @Nullable private final DisplayConfig displayConfig;
+    @Nullable private final AudioConfig audioConfig;
+    private final boolean touch;
+    private final boolean keyboard;
+    private final boolean mouse;
+    private final boolean switches;
+    private final boolean network;
+    @Nullable private final GpuConfig gpuConfig;
+    private final boolean trackpad;
+    private final boolean autoMemoryBalloon;
+
+    @Nullable
+    public Disk[] getDisks() {
+        return disks;
+    }
+
+    @Nullable
+    public String getBootloaderPath() {
+        return bootloaderPath;
+    }
+
+    @Nullable
+    public String getInitrdPath() {
+        return initrdPath;
+    }
+
+    @Nullable
+    public String getKernelPath() {
+        return kernelPath;
+    }
+
+    @Nullable
+    public String getName() {
+        return name;
+    }
+
+    @Nullable
+    public String[] getParams() {
+        return params;
+    }
+
+    public boolean useTouch() {
+        return touch;
+    }
+
+    public boolean useKeyboard() {
+        return keyboard;
+    }
+
+    public boolean useMouse() {
+        return mouse;
+    }
+
+    public boolean useSwitches() {
+        return switches;
+    }
+
+    public boolean useTrackpad() {
+        return mouse;
+    }
+
+    public boolean useAutoMemoryBalloon() {
+        return autoMemoryBalloon;
+    }
+
+    public boolean useNetwork() {
+        return network;
+    }
+
+    /** @hide */
+    public VirtualMachineCustomImageConfig(
+            String name,
+            String kernelPath,
+            String initrdPath,
+            String bootloaderPath,
+            String[] params,
+            Disk[] disks,
+            DisplayConfig displayConfig,
+            boolean touch,
+            boolean keyboard,
+            boolean mouse,
+            boolean switches,
+            boolean network,
+            GpuConfig gpuConfig,
+            AudioConfig audioConfig,
+            boolean trackpad,
+            boolean autoMemoryBalloon) {
+        this.name = name;
+        this.kernelPath = kernelPath;
+        this.initrdPath = initrdPath;
+        this.bootloaderPath = bootloaderPath;
+        this.params = params;
+        this.disks = disks;
+        this.displayConfig = displayConfig;
+        this.touch = touch;
+        this.keyboard = keyboard;
+        this.mouse = mouse;
+        this.switches = switches;
+        this.network = network;
+        this.gpuConfig = gpuConfig;
+        this.audioConfig = audioConfig;
+        this.trackpad = trackpad;
+        this.autoMemoryBalloon = autoMemoryBalloon;
+    }
+
+    static VirtualMachineCustomImageConfig from(PersistableBundle customImageConfigBundle) {
+        Builder builder = new Builder();
+        builder.setName(customImageConfigBundle.getString(KEY_NAME));
+        builder.setKernelPath(customImageConfigBundle.getString(KEY_KERNEL));
+        builder.setInitrdPath(customImageConfigBundle.getString(KEY_INITRD));
+        builder.setBootloaderPath(customImageConfigBundle.getString(KEY_BOOTLOADER));
+        String[] params = customImageConfigBundle.getStringArray(KEY_PARAMS);
+        if (params != null) {
+            for (String param : params) {
+                builder.addParam(param);
+            }
+        }
+        boolean[] writables = customImageConfigBundle.getBooleanArray(KEY_DISK_WRITABLES);
+        String[] diskImages = customImageConfigBundle.getStringArray(KEY_DISK_IMAGES);
+        if (writables != null && diskImages != null) {
+            if (writables.length == diskImages.length) {
+                for (int i = 0; i < writables.length; i++) {
+                    String diskImage = diskImages[i];
+                    diskImage = diskImage.equals("") ? null : diskImage;
+                    Disk disk = writables[i] ? Disk.RWDisk(diskImage) : Disk.RODisk(diskImage);
+                    String[] labels =
+                            customImageConfigBundle.getStringArray(KEY_PARTITION_LABELS + i);
+                    String[] images =
+                            customImageConfigBundle.getStringArray(KEY_PARTITION_IMAGES + i);
+                    boolean[] partitionWritables =
+                            customImageConfigBundle.getBooleanArray(KEY_PARTITION_WRITABLES + i);
+                    String[] guids =
+                            customImageConfigBundle.getStringArray(KEY_PARTITION_GUIDS + i);
+                    for (int j = 0; j < labels.length; j++) {
+                        disk.addPartition(
+                                new Partition(
+                                        labels[j], images[j], partitionWritables[j], guids[j]));
+                    }
+                    builder.addDisk(disk);
+                }
+            }
+        }
+        PersistableBundle displayConfigPb =
+                customImageConfigBundle.getPersistableBundle(KEY_DISPLAY_CONFIG);
+        builder.setDisplayConfig(DisplayConfig.from(displayConfigPb));
+        builder.useTouch(customImageConfigBundle.getBoolean(KEY_TOUCH));
+        builder.useKeyboard(customImageConfigBundle.getBoolean(KEY_KEYBOARD));
+        builder.useMouse(customImageConfigBundle.getBoolean(KEY_MOUSE));
+        builder.useNetwork(customImageConfigBundle.getBoolean(KEY_NETWORK));
+        builder.setGpuConfig(GpuConfig.from(customImageConfigBundle.getPersistableBundle(KEY_GPU)));
+        PersistableBundle audioConfigPb =
+                customImageConfigBundle.getPersistableBundle(KEY_AUDIO_CONFIG);
+        builder.setAudioConfig(AudioConfig.from(audioConfigPb));
+        builder.useTrackpad(customImageConfigBundle.getBoolean(KEY_TRACKPAD));
+        builder.useAutoMemoryBalloon(customImageConfigBundle.getBoolean(KEY_AUTO_MEMORY_BALLOON));
+        return builder.build();
+    }
+
+    PersistableBundle toPersistableBundle() {
+        PersistableBundle pb = new PersistableBundle();
+        pb.putString(KEY_NAME, this.name);
+        pb.putString(KEY_KERNEL, this.kernelPath);
+        pb.putString(KEY_BOOTLOADER, this.bootloaderPath);
+        pb.putString(KEY_INITRD, this.initrdPath);
+        pb.putStringArray(KEY_PARAMS, this.params);
+
+        if (disks != null) {
+            boolean[] writables = new boolean[disks.length];
+            String[] images = new String[disks.length];
+            for (int i = 0; i < disks.length; i++) {
+                writables[i] = disks[i].writable;
+                String imagePath = disks[i].imagePath;
+                images[i] = imagePath == null ? "" : imagePath;
+
+                int numPartitions = disks[i].getPartitions().size();
+                String[] partitionLabels = new String[numPartitions];
+                String[] partitionImages = new String[numPartitions];
+                boolean[] partitionWritables = new boolean[numPartitions];
+                String[] partitionGuids = new String[numPartitions];
+
+                for (int j = 0; j < numPartitions; j++) {
+                    Partition p = disks[i].getPartitions().get(j);
+                    partitionLabels[j] = p.name;
+                    partitionImages[j] = p.imagePath;
+                    partitionWritables[j] = p.writable;
+                    partitionGuids[j] = p.guid == null ? "" : p.guid;
+                }
+                pb.putStringArray(KEY_PARTITION_LABELS + i, partitionLabels);
+                pb.putStringArray(KEY_PARTITION_IMAGES + i, partitionImages);
+                pb.putBooleanArray(KEY_PARTITION_WRITABLES + i, partitionWritables);
+                pb.putStringArray(KEY_PARTITION_GUIDS + i, partitionGuids);
+            }
+            pb.putBooleanArray(KEY_DISK_WRITABLES, writables);
+            pb.putStringArray(KEY_DISK_IMAGES, images);
+        }
+        pb.putPersistableBundle(
+                KEY_DISPLAY_CONFIG,
+                Optional.ofNullable(displayConfig)
+                        .map(dc -> dc.toPersistableBundle())
+                        .orElse(null));
+        pb.putBoolean(KEY_TOUCH, touch);
+        pb.putBoolean(KEY_KEYBOARD, keyboard);
+        pb.putBoolean(KEY_MOUSE, mouse);
+        pb.putBoolean(KEY_SWITCHES, switches);
+        pb.putBoolean(KEY_NETWORK, network);
+        pb.putPersistableBundle(
+                KEY_GPU,
+                Optional.ofNullable(gpuConfig).map(gc -> gc.toPersistableBundle()).orElse(null));
+        pb.putPersistableBundle(
+                KEY_AUDIO_CONFIG,
+                Optional.ofNullable(audioConfig).map(ac -> ac.toPersistableBundle()).orElse(null));
+        pb.putBoolean(KEY_TRACKPAD, trackpad);
+        pb.putBoolean(KEY_AUTO_MEMORY_BALLOON, autoMemoryBalloon);
+        return pb;
+    }
+
+    @Nullable
+    public AudioConfig getAudioConfig() {
+        return audioConfig;
+    }
+
+    @Nullable
+    public DisplayConfig getDisplayConfig() {
+        return displayConfig;
+    }
+
+    @Nullable
+    public GpuConfig getGpuConfig() {
+        return gpuConfig;
+    }
+
+    /** @hide */
+    public static final class Disk {
+        private final boolean writable;
+        private final String imagePath;
+        private final List<Partition> partitions;
+
+        private Disk(boolean writable, String imagePath) {
+            this.writable = writable;
+            this.imagePath = imagePath;
+            this.partitions = new ArrayList<>();
+        }
+
+        /** @hide */
+        public static Disk RWDisk(String imagePath) {
+            return new Disk(true, imagePath);
+        }
+
+        /** @hide */
+        public static Disk RODisk(String imagePath) {
+            return new Disk(false, imagePath);
+        }
+
+        /** @hide */
+        public boolean isWritable() {
+            return writable;
+        }
+
+        /** @hide */
+        public String getImagePath() {
+            return imagePath;
+        }
+
+        /** @hide */
+        public Disk addPartition(Partition p) {
+            this.partitions.add(p);
+            return this;
+        }
+
+        /** @hide */
+        public List<Partition> getPartitions() {
+            return partitions;
+        }
+    }
+
+    /** @hide */
+    public static final class Partition {
+        public final String name;
+        public final String imagePath;
+        public final boolean writable;
+        public final String guid;
+
+        public Partition(String name, String imagePath, boolean writable, String guid) {
+            this.name = name;
+            this.imagePath = imagePath;
+            this.writable = writable;
+            this.guid = guid;
+        }
+    }
+
+    /** @hide */
+    public static final class Builder {
+        private String name;
+        private String kernelPath;
+        private String initrdPath;
+        private String bootloaderPath;
+        private List<String> params = new ArrayList<>();
+        private List<Disk> disks = new ArrayList<>();
+        private AudioConfig audioConfig;
+        private DisplayConfig displayConfig;
+        private boolean touch;
+        private boolean keyboard;
+        private boolean mouse;
+        private boolean switches;
+        private boolean network;
+        private GpuConfig gpuConfig;
+        private boolean trackpad;
+        private boolean autoMemoryBalloon = true;
+
+        /** @hide */
+        public Builder() {}
+
+        /** @hide */
+        public Builder setName(String name) {
+            this.name = name;
+            return this;
+        }
+
+        /** @hide */
+        public Builder setKernelPath(String kernelPath) {
+            this.kernelPath = kernelPath;
+            return this;
+        }
+
+        /** @hide */
+        public Builder setBootloaderPath(String bootloaderPath) {
+            this.bootloaderPath = bootloaderPath;
+            return this;
+        }
+
+        /** @hide */
+        public Builder setInitrdPath(String initrdPath) {
+            this.initrdPath = initrdPath;
+            return this;
+        }
+
+        /** @hide */
+        public Builder addDisk(Disk disk) {
+            this.disks.add(disk);
+            return this;
+        }
+
+        /** @hide */
+        public Builder addParam(String param) {
+            this.params.add(param);
+            return this;
+        }
+
+        /** @hide */
+        public Builder setDisplayConfig(DisplayConfig displayConfig) {
+            this.displayConfig = displayConfig;
+            return this;
+        }
+
+        /** @hide */
+        public Builder setGpuConfig(GpuConfig gpuConfig) {
+            this.gpuConfig = gpuConfig;
+            return this;
+        }
+
+        /** @hide */
+        public Builder useTouch(boolean touch) {
+            this.touch = touch;
+            return this;
+        }
+
+        /** @hide */
+        public Builder useKeyboard(boolean keyboard) {
+            this.keyboard = keyboard;
+            return this;
+        }
+
+        /** @hide */
+        public Builder useMouse(boolean mouse) {
+            this.mouse = mouse;
+            return this;
+        }
+
+        /** @hide */
+        public Builder useSwitches(boolean switches) {
+            this.switches = switches;
+            return this;
+        }
+
+        /** @hide */
+        public Builder useTrackpad(boolean trackpad) {
+            this.trackpad = trackpad;
+            return this;
+        }
+
+        /** @hide */
+        public Builder useAutoMemoryBalloon(boolean autoMemoryBalloon) {
+            this.autoMemoryBalloon = autoMemoryBalloon;
+            return this;
+        }
+
+        /** @hide */
+        public Builder useNetwork(boolean network) {
+            this.network = network;
+            return this;
+        }
+
+        /** @hide */
+        public Builder setAudioConfig(AudioConfig audioConfig) {
+            this.audioConfig = audioConfig;
+            return this;
+        }
+
+        /** @hide */
+        public VirtualMachineCustomImageConfig build() {
+            return new VirtualMachineCustomImageConfig(
+                    this.name,
+                    this.kernelPath,
+                    this.initrdPath,
+                    this.bootloaderPath,
+                    this.params.toArray(new String[0]),
+                    this.disks.toArray(new Disk[0]),
+                    displayConfig,
+                    touch,
+                    keyboard,
+                    mouse,
+                    switches,
+                    network,
+                    gpuConfig,
+                    audioConfig,
+                    trackpad,
+                    autoMemoryBalloon);
+        }
+    }
+
+    /** @hide */
+    public static final class AudioConfig {
+        private static final String KEY_USE_MICROPHONE = "use_microphone";
+        private static final String KEY_USE_SPEAKER = "use_speaker";
+        private final boolean useMicrophone;
+        private final boolean useSpeaker;
+
+        private AudioConfig(boolean useMicrophone, boolean useSpeaker) {
+            this.useMicrophone = useMicrophone;
+            this.useSpeaker = useSpeaker;
+        }
+
+        /** @hide */
+        public boolean useMicrophone() {
+            return useMicrophone;
+        }
+
+        /** @hide */
+        public boolean useSpeaker() {
+            return useSpeaker;
+        }
+
+        android.system.virtualizationservice.AudioConfig toParcelable() {
+            android.system.virtualizationservice.AudioConfig parcelable =
+                    new android.system.virtualizationservice.AudioConfig();
+            parcelable.useSpeaker = this.useSpeaker;
+            parcelable.useMicrophone = this.useMicrophone;
+
+            return parcelable;
+        }
+
+        private static AudioConfig from(PersistableBundle pb) {
+            if (pb == null) {
+                return null;
+            }
+            Builder builder = new Builder();
+            builder.setUseMicrophone(pb.getBoolean(KEY_USE_MICROPHONE));
+            builder.setUseSpeaker(pb.getBoolean(KEY_USE_SPEAKER));
+            return builder.build();
+        }
+
+        private PersistableBundle toPersistableBundle() {
+            PersistableBundle pb = new PersistableBundle();
+            pb.putBoolean(KEY_USE_MICROPHONE, this.useMicrophone);
+            pb.putBoolean(KEY_USE_SPEAKER, this.useSpeaker);
+            return pb;
+        }
+
+        /** @hide */
+        public static class Builder {
+            private boolean useMicrophone = false;
+            private boolean useSpeaker = false;
+
+            /** @hide */
+            public Builder() {}
+
+            /** @hide */
+            public Builder setUseMicrophone(boolean useMicrophone) {
+                this.useMicrophone = useMicrophone;
+                return this;
+            }
+
+            /** @hide */
+            public Builder setUseSpeaker(boolean useSpeaker) {
+                this.useSpeaker = useSpeaker;
+                return this;
+            }
+
+            /** @hide */
+            public AudioConfig build() {
+                return new AudioConfig(useMicrophone, useSpeaker);
+            }
+        }
+    }
+
+    /** @hide */
+    public static final class DisplayConfig {
+        private static final String KEY_WIDTH = "width";
+        private static final String KEY_HEIGHT = "height";
+        private static final String KEY_HORIZONTAL_DPI = "horizontal_dpi";
+        private static final String KEY_VERTICAL_DPI = "vertical_dpi";
+        private static final String KEY_REFRESH_RATE = "refresh_rate";
+        private final int width;
+        private final int height;
+        private final int horizontalDpi;
+        private final int verticalDpi;
+        private final int refreshRate;
+
+        private DisplayConfig(
+                int width, int height, int horizontalDpi, int verticalDpi, int refreshRate) {
+            this.width = width;
+            this.height = height;
+            this.horizontalDpi = horizontalDpi;
+            this.verticalDpi = verticalDpi;
+            this.refreshRate = refreshRate;
+        }
+
+        /** @hide */
+        public int getWidth() {
+            return width;
+        }
+
+        /** @hide */
+        public int getHeight() {
+            return height;
+        }
+
+        /** @hide */
+        public int getHorizontalDpi() {
+            return horizontalDpi;
+        }
+
+        /** @hide */
+        public int getVerticalDpi() {
+            return verticalDpi;
+        }
+
+        /** @hide */
+        public int getRefreshRate() {
+            return refreshRate;
+        }
+
+        android.system.virtualizationservice.DisplayConfig toParcelable() {
+            android.system.virtualizationservice.DisplayConfig parcelable =
+                    new android.system.virtualizationservice.DisplayConfig();
+            parcelable.width = this.width;
+            parcelable.height = this.height;
+            parcelable.horizontalDpi = this.horizontalDpi;
+            parcelable.verticalDpi = this.verticalDpi;
+            parcelable.refreshRate = this.refreshRate;
+
+            return parcelable;
+        }
+
+        private static DisplayConfig from(PersistableBundle pb) {
+            if (pb == null) {
+                return null;
+            }
+            Builder builder = new Builder();
+            builder.setWidth(pb.getInt(KEY_WIDTH));
+            builder.setHeight(pb.getInt(KEY_HEIGHT));
+            builder.setHorizontalDpi(pb.getInt(KEY_HORIZONTAL_DPI));
+            builder.setVerticalDpi(pb.getInt(KEY_VERTICAL_DPI));
+            builder.setRefreshRate(pb.getInt(KEY_REFRESH_RATE));
+            return builder.build();
+        }
+
+        private PersistableBundle toPersistableBundle() {
+            PersistableBundle pb = new PersistableBundle();
+            pb.putInt(KEY_WIDTH, this.width);
+            pb.putInt(KEY_HEIGHT, this.height);
+            pb.putInt(KEY_HORIZONTAL_DPI, this.horizontalDpi);
+            pb.putInt(KEY_VERTICAL_DPI, this.verticalDpi);
+            pb.putInt(KEY_REFRESH_RATE, this.refreshRate);
+            return pb;
+        }
+
+        /** @hide */
+        public static class Builder {
+            // Default values come from external/crosvm/vm_control/src/gpu.rs
+            private int width;
+            private int height;
+            private int horizontalDpi = 320;
+            private int verticalDpi = 320;
+            private int refreshRate = 60;
+
+            /** @hide */
+            public Builder() {}
+
+            /** @hide */
+            public Builder setWidth(int width) {
+                this.width = width;
+                return this;
+            }
+
+            /** @hide */
+            public Builder setHeight(int height) {
+                this.height = height;
+                return this;
+            }
+
+            /** @hide */
+            public Builder setHorizontalDpi(int horizontalDpi) {
+                this.horizontalDpi = horizontalDpi;
+                return this;
+            }
+
+            /** @hide */
+            public Builder setVerticalDpi(int verticalDpi) {
+                this.verticalDpi = verticalDpi;
+                return this;
+            }
+
+            /** @hide */
+            public Builder setRefreshRate(int refreshRate) {
+                this.refreshRate = refreshRate;
+                return this;
+            }
+
+            /** @hide */
+            public DisplayConfig build() {
+                if (this.width == 0 || this.height == 0) {
+                    throw new IllegalStateException("width and height must be specified");
+                }
+                return new DisplayConfig(width, height, horizontalDpi, verticalDpi, refreshRate);
+            }
+        }
+    }
+
+    /** @hide */
+    public static final class GpuConfig {
+        private static final String KEY_BACKEND = "backend";
+        private static final String KEY_CONTEXT_TYPES = "context_types";
+        private static final String KEY_PCI_ADDRESS = "pci_address";
+        private static final String KEY_RENDERER_FEATURES = "renderer_features";
+        private static final String KEY_RENDERER_USE_EGL = "renderer_use_egl";
+        private static final String KEY_RENDERER_USE_GLES = "renderer_use_gles";
+        private static final String KEY_RENDERER_USE_GLX = "renderer_use_glx";
+        private static final String KEY_RENDERER_USE_SURFACELESS = "renderer_use_surfaceless";
+        private static final String KEY_RENDERER_USE_VULKAN = "renderer_use_vulkan";
+
+        private final String backend;
+        private final String[] contextTypes;
+        private final String pciAddress;
+        private final String rendererFeatures;
+        private final boolean rendererUseEgl;
+        private final boolean rendererUseGles;
+        private final boolean rendererUseGlx;
+        private final boolean rendererUseSurfaceless;
+        private final boolean rendererUseVulkan;
+
+        private GpuConfig(
+                String backend,
+                String[] contextTypes,
+                String pciAddress,
+                String rendererFeatures,
+                boolean rendererUseEgl,
+                boolean rendererUseGles,
+                boolean rendererUseGlx,
+                boolean rendererUseSurfaceless,
+                boolean rendererUseVulkan) {
+            this.backend = backend;
+            this.contextTypes = contextTypes;
+            this.pciAddress = pciAddress;
+            this.rendererFeatures = rendererFeatures;
+            this.rendererUseEgl = rendererUseEgl;
+            this.rendererUseGles = rendererUseGles;
+            this.rendererUseGlx = rendererUseGlx;
+            this.rendererUseSurfaceless = rendererUseSurfaceless;
+            this.rendererUseVulkan = rendererUseVulkan;
+        }
+
+        /** @hide */
+        public String getBackend() {
+            return backend;
+        }
+
+        /** @hide */
+        public String[] getContextTypes() {
+            return contextTypes;
+        }
+
+        /** @hide */
+        public String getPciAddress() {
+            return pciAddress;
+        }
+
+        /** @hide */
+        public String getRendererFeatures() {
+            return rendererFeatures;
+        }
+
+        /** @hide */
+        public boolean getRendererUseEgl() {
+            return rendererUseEgl;
+        }
+
+        /** @hide */
+        public boolean getRendererUseGles() {
+            return rendererUseGles;
+        }
+
+        /** @hide */
+        public boolean getRendererUseGlx() {
+            return rendererUseGlx;
+        }
+
+        /** @hide */
+        public boolean getRendererUseSurfaceless() {
+            return rendererUseSurfaceless;
+        }
+
+        /** @hide */
+        public boolean getRendererUseVulkan() {
+            return rendererUseVulkan;
+        }
+
+        android.system.virtualizationservice.GpuConfig toParcelable() {
+            android.system.virtualizationservice.GpuConfig parcelable =
+                    new android.system.virtualizationservice.GpuConfig();
+            parcelable.backend = this.backend;
+            parcelable.contextTypes = this.contextTypes;
+            parcelable.pciAddress = this.pciAddress;
+            parcelable.rendererFeatures = this.rendererFeatures;
+            parcelable.rendererUseEgl = this.rendererUseEgl;
+            parcelable.rendererUseGles = this.rendererUseGles;
+            parcelable.rendererUseGlx = this.rendererUseGlx;
+            parcelable.rendererUseSurfaceless = this.rendererUseSurfaceless;
+            parcelable.rendererUseVulkan = this.rendererUseVulkan;
+            return parcelable;
+        }
+
+        private static GpuConfig from(PersistableBundle pb) {
+            if (pb == null) {
+                return null;
+            }
+            Builder builder = new Builder();
+            builder.setBackend(pb.getString(KEY_BACKEND));
+            builder.setContextTypes(pb.getStringArray(KEY_CONTEXT_TYPES));
+            builder.setPciAddress(pb.getString(KEY_PCI_ADDRESS));
+            builder.setRendererFeatures(pb.getString(KEY_RENDERER_FEATURES));
+            builder.setRendererUseEgl(pb.getBoolean(KEY_RENDERER_USE_EGL));
+            builder.setRendererUseGles(pb.getBoolean(KEY_RENDERER_USE_GLES));
+            builder.setRendererUseGlx(pb.getBoolean(KEY_RENDERER_USE_GLX));
+            builder.setRendererUseSurfaceless(pb.getBoolean(KEY_RENDERER_USE_SURFACELESS));
+            builder.setRendererUseVulkan(pb.getBoolean(KEY_RENDERER_USE_VULKAN));
+            return builder.build();
+        }
+
+        private PersistableBundle toPersistableBundle() {
+            PersistableBundle pb = new PersistableBundle();
+            pb.putString(KEY_BACKEND, this.backend);
+            pb.putStringArray(KEY_CONTEXT_TYPES, this.contextTypes);
+            pb.putString(KEY_PCI_ADDRESS, this.pciAddress);
+            pb.putString(KEY_RENDERER_FEATURES, this.rendererFeatures);
+            pb.putBoolean(KEY_RENDERER_USE_EGL, this.rendererUseEgl);
+            pb.putBoolean(KEY_RENDERER_USE_GLES, this.rendererUseGles);
+            pb.putBoolean(KEY_RENDERER_USE_GLX, this.rendererUseGlx);
+            pb.putBoolean(KEY_RENDERER_USE_SURFACELESS, this.rendererUseSurfaceless);
+            pb.putBoolean(KEY_RENDERER_USE_VULKAN, this.rendererUseVulkan);
+            return pb;
+        }
+
+        /** @hide */
+        public static class Builder {
+            private String backend;
+            private String[] contextTypes;
+            private String pciAddress;
+            private String rendererFeatures;
+            private boolean rendererUseEgl = true;
+            private boolean rendererUseGles = true;
+            private boolean rendererUseGlx = false;
+            private boolean rendererUseSurfaceless = true;
+            private boolean rendererUseVulkan = false;
+
+            /** @hide */
+            public Builder() {}
+
+            /** @hide */
+            public Builder setBackend(String backend) {
+                this.backend = backend;
+                return this;
+            }
+
+            /** @hide */
+            public Builder setContextTypes(String[] contextTypes) {
+                this.contextTypes = contextTypes;
+                return this;
+            }
+
+            /** @hide */
+            public Builder setPciAddress(String pciAddress) {
+                this.pciAddress = pciAddress;
+                return this;
+            }
+
+            /** @hide */
+            public Builder setRendererFeatures(String rendererFeatures) {
+                this.rendererFeatures = rendererFeatures;
+                return this;
+            }
+
+            /** @hide */
+            public Builder setRendererUseEgl(Boolean rendererUseEgl) {
+                this.rendererUseEgl = rendererUseEgl;
+                return this;
+            }
+
+            /** @hide */
+            public Builder setRendererUseGles(Boolean rendererUseGles) {
+                this.rendererUseGles = rendererUseGles;
+                return this;
+            }
+
+            /** @hide */
+            public Builder setRendererUseGlx(Boolean rendererUseGlx) {
+                this.rendererUseGlx = rendererUseGlx;
+                return this;
+            }
+
+            /** @hide */
+            public Builder setRendererUseSurfaceless(Boolean rendererUseSurfaceless) {
+                this.rendererUseSurfaceless = rendererUseSurfaceless;
+                return this;
+            }
+
+            /** @hide */
+            public Builder setRendererUseVulkan(Boolean rendererUseVulkan) {
+                this.rendererUseVulkan = rendererUseVulkan;
+                return this;
+            }
+
+            /** @hide */
+            public GpuConfig build() {
+                return new GpuConfig(
+                        backend,
+                        contextTypes,
+                        pciAddress,
+                        rendererFeatures,
+                        rendererUseEgl,
+                        rendererUseGles,
+                        rendererUseGlx,
+                        rendererUseSurfaceless,
+                        rendererUseVulkan);
+            }
+        }
+    }
+}
diff --git a/libs/framework-virtualization/src/android/system/virtualmachine/VirtualMachineDescriptor.java b/libs/framework-virtualization/src/android/system/virtualmachine/VirtualMachineDescriptor.java
new file mode 100644
index 0000000..ee79256
--- /dev/null
+++ b/libs/framework-virtualization/src/android/system/virtualmachine/VirtualMachineDescriptor.java
@@ -0,0 +1,160 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.system.virtualmachine;
+
+import static java.util.Objects.requireNonNull;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.ParcelFileDescriptor;
+import android.os.Parcelable;
+
+import java.io.IOException;
+
+/**
+ * A VM descriptor that captures the state of a Virtual Machine.
+ *
+ * <p>You can capture the current state of VM by creating an instance of this class with {@link
+ * VirtualMachine#toDescriptor}, optionally pass it to another App, and then build an identical VM
+ * with the descriptor received.
+ *
+ * @hide
+ */
+@SystemApi
+public final class VirtualMachineDescriptor implements Parcelable, AutoCloseable {
+    private volatile boolean mClosed = false;
+    @NonNull private final ParcelFileDescriptor mConfigFd;
+    // File descriptor of the file containing the instance id - will be null iff
+    // FEATURE_LLPVM_CHANGES is disabled.
+    @Nullable private final ParcelFileDescriptor mInstanceIdFd;
+    @NonNull private final ParcelFileDescriptor mInstanceImgFd;
+    // File descriptor of the image backing the encrypted storage - Will be null if encrypted
+    // storage is not enabled. */
+    @Nullable private final ParcelFileDescriptor mEncryptedStoreFd;
+
+    @Override
+    public int describeContents() {
+        return CONTENTS_FILE_DESCRIPTOR;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel out, int flags) {
+        checkNotClosed();
+        out.writeParcelable(mConfigFd, flags);
+        out.writeParcelable(mInstanceIdFd, flags);
+        out.writeParcelable(mInstanceImgFd, flags);
+        out.writeParcelable(mEncryptedStoreFd, flags);
+    }
+
+    @NonNull
+    public static final Parcelable.Creator<VirtualMachineDescriptor> CREATOR =
+            new Parcelable.Creator<>() {
+                public VirtualMachineDescriptor createFromParcel(Parcel in) {
+                    return new VirtualMachineDescriptor(in);
+                }
+
+                public VirtualMachineDescriptor[] newArray(int size) {
+                    return new VirtualMachineDescriptor[size];
+                }
+            };
+
+    /**
+     * @return File descriptor of the VM configuration file config.xml.
+     */
+    @NonNull
+    ParcelFileDescriptor getConfigFd() {
+        checkNotClosed();
+        return mConfigFd;
+    }
+
+    /**
+     * @return File descriptor of the file containing instance_id of the VM.
+     */
+    @Nullable
+    ParcelFileDescriptor getInstanceIdFd() {
+        checkNotClosed();
+        return mInstanceIdFd;
+    }
+
+    /**
+     * @return File descriptor of the instance.img of the VM.
+     */
+    @NonNull
+    ParcelFileDescriptor getInstanceImgFd() {
+        checkNotClosed();
+        return mInstanceImgFd;
+    }
+
+    /**
+     * @return File descriptor of image backing the encrypted storage.
+     *     <p>This method will return null if encrypted storage is not enabled.
+     */
+    @Nullable
+    ParcelFileDescriptor getEncryptedStoreFd() {
+        checkNotClosed();
+        return mEncryptedStoreFd;
+    }
+
+    VirtualMachineDescriptor(
+            @NonNull ParcelFileDescriptor configFd,
+            @Nullable ParcelFileDescriptor instanceIdFd,
+            @NonNull ParcelFileDescriptor instanceImgFd,
+            @Nullable ParcelFileDescriptor encryptedStoreFd) {
+        mConfigFd = requireNonNull(configFd);
+        mInstanceIdFd = instanceIdFd;
+        mInstanceImgFd = requireNonNull(instanceImgFd);
+        mEncryptedStoreFd = encryptedStoreFd;
+    }
+
+    private VirtualMachineDescriptor(Parcel in) {
+        mConfigFd = requireNonNull(readParcelFileDescriptor(in));
+        mInstanceIdFd = readParcelFileDescriptor(in);
+        mInstanceImgFd = requireNonNull(readParcelFileDescriptor(in));
+        mEncryptedStoreFd = readParcelFileDescriptor(in);
+    }
+
+    private ParcelFileDescriptor readParcelFileDescriptor(Parcel in) {
+        return in.readParcelable(
+                ParcelFileDescriptor.class.getClassLoader(), ParcelFileDescriptor.class);
+    }
+
+    /**
+     * Release any resources held by this descriptor. Calling {@code close} on an already-closed
+     * descriptor has no effect.
+     */
+    @Override
+    public void close() {
+        mClosed = true;
+        // Let the compiler do the work: close everything, throw if any of them fail, skipping null.
+        try (mConfigFd;
+                mInstanceIdFd;
+                mInstanceImgFd;
+                mEncryptedStoreFd) {
+        } catch (IOException ignored) {
+            // PFD already swallows exceptions from closing the fd. There's no reason to propagate
+            // this to the caller.
+        }
+    }
+
+    private void checkNotClosed() {
+        if (mClosed) {
+            throw new IllegalStateException("Descriptor has been closed");
+        }
+    }
+}
diff --git a/libs/framework-virtualization/src/android/system/virtualmachine/VirtualMachineException.java b/libs/framework-virtualization/src/android/system/virtualmachine/VirtualMachineException.java
new file mode 100644
index 0000000..9948fda
--- /dev/null
+++ b/libs/framework-virtualization/src/android/system/virtualmachine/VirtualMachineException.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.system.virtualmachine;
+
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+
+/**
+ * Exception thrown when operations on virtual machines fail.
+ *
+ * @hide
+ */
+@SystemApi
+public class VirtualMachineException extends Exception {
+    VirtualMachineException(@Nullable String message) {
+        super(message);
+    }
+
+    VirtualMachineException(@Nullable String message, @Nullable Throwable cause) {
+        super(message, cause);
+    }
+
+    VirtualMachineException(@Nullable Throwable cause) {
+        super(cause);
+    }
+}
diff --git a/libs/framework-virtualization/src/android/system/virtualmachine/VirtualMachineManager.java b/libs/framework-virtualization/src/android/system/virtualmachine/VirtualMachineManager.java
new file mode 100644
index 0000000..242dc91
--- /dev/null
+++ b/libs/framework-virtualization/src/android/system/virtualmachine/VirtualMachineManager.java
@@ -0,0 +1,469 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.system.virtualmachine;
+
+import static java.util.Objects.requireNonNull;
+
+import android.annotation.FlaggedApi;
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.RequiresFeature;
+import android.annotation.RequiresPermission;
+import android.annotation.StringDef;
+import android.annotation.SystemApi;
+import android.annotation.TestApi;
+import android.annotation.WorkerThread;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.os.RemoteException;
+import android.sysprop.HypervisorProperties;
+import android.system.virtualizationservice.IVirtualizationService;
+import android.util.ArrayMap;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.system.virtualmachine.flags.Flags;
+
+import java.io.File;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.ref.WeakReference;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Manages {@linkplain VirtualMachine virtual machine} instances created by an app. Each instance is
+ * created from a {@linkplain VirtualMachineConfig configuration} that defines the shape of the VM
+ * (RAM, CPUs), the code to execute within it, etc.
+ *
+ * <p>Each virtual machine instance is named; the configuration and related state of each is
+ * persisted in the app's private data directory and an instance can be retrieved given the name.
+ * The name must be a valid directory name and must not contain '/'.
+ *
+ * <p>The app can then start, stop and otherwise interact with the VM.
+ *
+ * <p>An instance of {@link VirtualMachineManager} can be obtained by calling {@link
+ * Context#getSystemService(Class)}.
+ *
+ * @hide
+ */
+@SystemApi
+@RequiresFeature(PackageManager.FEATURE_VIRTUALIZATION_FRAMEWORK)
+public class VirtualMachineManager {
+    /**
+     * A lock used to synchronize the creation of virtual machines. It protects {@link #mVmsByName},
+     * but is also held throughout VM creation / retrieval / deletion, to prevent these actions
+     * racing with each other.
+     */
+    private static final Object sCreateLock = new Object();
+
+    @NonNull private final Context mContext;
+
+    /** @hide */
+    public VirtualMachineManager(@NonNull Context context) {
+        mContext = requireNonNull(context);
+    }
+
+    @GuardedBy("sCreateLock")
+    private final Map<String, WeakReference<VirtualMachine>> mVmsByName = new ArrayMap<>();
+
+    /**
+     * Capabilities of the virtual machine implementation.
+     *
+     * @hide
+     */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(
+            prefix = "CAPABILITY_",
+            flag = true,
+            value = {CAPABILITY_PROTECTED_VM, CAPABILITY_NON_PROTECTED_VM})
+    public @interface Capability {}
+
+    /**
+     * The implementation supports creating protected VMs, whose memory is inaccessible to the host
+     * OS.
+     *
+     * @see VirtualMachineConfig.Builder#setProtectedVm
+     */
+    public static final int CAPABILITY_PROTECTED_VM = 1;
+
+    /**
+     * The implementation supports creating non-protected VMs, whose memory is accessible to the
+     * host OS.
+     *
+     * @see VirtualMachineConfig.Builder#setProtectedVm
+     */
+    public static final int CAPABILITY_NON_PROTECTED_VM = 2;
+
+    /**
+     * Features provided by {@link VirtualMachineManager}.
+     *
+     * @hide
+     */
+    @Retention(RetentionPolicy.SOURCE)
+    @StringDef(
+            prefix = "FEATURE_",
+            value = {
+                FEATURE_DICE_CHANGES,
+                FEATURE_LLPVM_CHANGES,
+                FEATURE_MULTI_TENANT,
+                FEATURE_NETWORK,
+                FEATURE_REMOTE_ATTESTATION,
+                FEATURE_VENDOR_MODULES,
+            })
+    public @interface Features {}
+
+    /**
+     * Feature to include new data in the VM DICE chain.
+     *
+     * @hide
+     */
+    @TestApi
+    @FlaggedApi(Flags.FLAG_AVF_V_TEST_APIS)
+    public static final String FEATURE_DICE_CHANGES = IVirtualizationService.FEATURE_DICE_CHANGES;
+
+    /**
+     * Feature to run payload as non-root user.
+     *
+     * @hide
+     */
+    @TestApi
+    @FlaggedApi(Flags.FLAG_AVF_V_TEST_APIS)
+    public static final String FEATURE_MULTI_TENANT = IVirtualizationService.FEATURE_MULTI_TENANT;
+
+    /**
+     * Feature to allow network features in VM.
+     *
+     * @hide
+     */
+    @TestApi public static final String FEATURE_NETWORK = IVirtualizationService.FEATURE_NETWORK;
+
+    /**
+     * Feature to allow remote attestation in Microdroid.
+     *
+     * @hide
+     */
+    @TestApi
+    @FlaggedApi(Flags.FLAG_AVF_V_TEST_APIS)
+    public static final String FEATURE_REMOTE_ATTESTATION =
+            IVirtualizationService.FEATURE_REMOTE_ATTESTATION;
+
+    /**
+     * Feature to allow vendor modules in Microdroid.
+     *
+     * @hide
+     */
+    @TestApi
+    @FlaggedApi(Flags.FLAG_AVF_V_TEST_APIS)
+    public static final String FEATURE_VENDOR_MODULES =
+            IVirtualizationService.FEATURE_VENDOR_MODULES;
+
+    /**
+     * Feature to enable Secretkeeper protected secrets in Microdroid based pVMs.
+     *
+     * @hide
+     */
+    @TestApi
+    @FlaggedApi(Flags.FLAG_AVF_V_TEST_APIS)
+    public static final String FEATURE_LLPVM_CHANGES = IVirtualizationService.FEATURE_LLPVM_CHANGES;
+
+    /**
+     * Returns a set of flags indicating what this implementation of virtualization is capable of.
+     *
+     * @see #CAPABILITY_PROTECTED_VM
+     * @see #CAPABILITY_NON_PROTECTED_VM
+     * @hide
+     */
+    @SystemApi
+    @Capability
+    public int getCapabilities() {
+        @Capability int result = 0;
+        if (HypervisorProperties.hypervisor_protected_vm_supported().orElse(false)) {
+            result |= CAPABILITY_PROTECTED_VM;
+        }
+        if (HypervisorProperties.hypervisor_vm_supported().orElse(false)) {
+            result |= CAPABILITY_NON_PROTECTED_VM;
+        }
+        return result;
+    }
+
+    /**
+     * Creates a new {@link VirtualMachine} with the given name and config. Creating a virtual
+     * machine with the same name as an existing virtual machine is an error. The existing virtual
+     * machine has to be deleted before its name can be reused.
+     *
+     * <p>Each successful call to this method creates a new (and different) virtual machine even if
+     * the name and the config are the same as a deleted one. The new virtual machine will initially
+     * be stopped.
+     *
+     * <p>NOTE: This method may block and should not be called on the main thread.
+     *
+     * @throws VirtualMachineException if the VM cannot be created, or there is an existing VM with
+     *     the given name.
+     * @hide
+     */
+    @SystemApi
+    @NonNull
+    @WorkerThread
+    @RequiresPermission(VirtualMachine.MANAGE_VIRTUAL_MACHINE_PERMISSION)
+    public VirtualMachine create(@NonNull String name, @NonNull VirtualMachineConfig config)
+            throws VirtualMachineException {
+        synchronized (sCreateLock) {
+            return createLocked(name, config);
+        }
+    }
+
+    @NonNull
+    @GuardedBy("sCreateLock")
+    private VirtualMachine createLocked(@NonNull String name, @NonNull VirtualMachineConfig config)
+            throws VirtualMachineException {
+        VirtualMachine vm = VirtualMachine.create(mContext, name, config);
+        mVmsByName.put(name, new WeakReference<>(vm));
+        return vm;
+    }
+
+    /**
+     * Returns an existing {@link VirtualMachine} with the given name. Returns null if there is no
+     * such virtual machine.
+     *
+     * <p>There is at most one {@code VirtualMachine} object corresponding to a given virtual
+     * machine instance. Multiple calls to get() passing the same name will get the same object
+     * returned, until the virtual machine is deleted (via {@link #delete}) and then recreated.
+     *
+     * <p>NOTE: This method may block and should not be called on the main thread.
+     *
+     * @see #getOrCreate
+     * @throws VirtualMachineException if the virtual machine exists but could not be successfully
+     *     retrieved. This can be resolved by calling {@link #delete} on the VM.
+     * @hide
+     */
+    @SystemApi
+    @WorkerThread
+    @Nullable
+    public VirtualMachine get(@NonNull String name) throws VirtualMachineException {
+        synchronized (sCreateLock) {
+            return getLocked(name);
+        }
+    }
+
+    @Nullable
+    @GuardedBy("sCreateLock")
+    private VirtualMachine getLocked(@NonNull String name) throws VirtualMachineException {
+        VirtualMachine vm = getVmByName(name);
+        if (vm != null) return vm;
+
+        vm = VirtualMachine.load(mContext, name);
+        if (vm != null) {
+            mVmsByName.put(name, new WeakReference<>(vm));
+        }
+        return vm;
+    }
+
+    /**
+     * Imports a virtual machine from an {@link VirtualMachineDescriptor} object and associates it
+     * with the given name.
+     *
+     * <p>The new virtual machine will be in the same state as the descriptor indicates. The
+     * descriptor is automatically closed and cannot be used again.
+     *
+     * <p>NOTE: This method may block and should not be called on the main thread.
+     *
+     * @throws VirtualMachineException if the VM cannot be imported or the {@code
+     *     VirtualMachineDescriptor} has already been closed.
+     * @hide
+     */
+    @NonNull
+    @SystemApi
+    @WorkerThread
+    public VirtualMachine importFromDescriptor(
+            @NonNull String name, @NonNull VirtualMachineDescriptor vmDescriptor)
+            throws VirtualMachineException {
+        VirtualMachine vm;
+        synchronized (sCreateLock) {
+            vm = VirtualMachine.fromDescriptor(mContext, name, vmDescriptor);
+            mVmsByName.put(name, new WeakReference<>(vm));
+        }
+        return vm;
+    }
+
+    /**
+     * Returns an existing {@link VirtualMachine} if it exists, or create a new one. The config
+     * parameter is used only when a new virtual machine is created.
+     *
+     * <p>NOTE: This method may block and should not be called on the main thread.
+     *
+     * @throws VirtualMachineException if the virtual machine could not be created or retrieved.
+     * @hide
+     */
+    @SystemApi
+    @WorkerThread
+    @NonNull
+    public VirtualMachine getOrCreate(@NonNull String name, @NonNull VirtualMachineConfig config)
+            throws VirtualMachineException {
+        synchronized (sCreateLock) {
+            VirtualMachine vm = getLocked(name);
+            if (vm != null) {
+                return vm;
+            } else {
+                return createLocked(name, config);
+            }
+        }
+    }
+
+    /**
+     * Deletes an existing {@link VirtualMachine}. Deleting a virtual machine means deleting any
+     * persisted data associated with it including the per-VM secret. This is an irreversible
+     * action. A virtual machine once deleted can never be restored. A new virtual machine created
+     * with the same name is different from an already deleted virtual machine even if it has the
+     * same config.
+     *
+     * <p>NOTE: This method may block and should not be called on the main thread.
+     *
+     * @throws VirtualMachineException if the virtual machine does not exist, is not stopped, or
+     *     cannot be deleted.
+     * @hide
+     */
+    @SystemApi
+    @WorkerThread
+    public void delete(@NonNull String name) throws VirtualMachineException {
+        synchronized (sCreateLock) {
+            VirtualMachine vm = getVmByName(name);
+            if (vm == null) {
+                VirtualMachine.vmInstanceCleanup(mContext, name);
+            } else {
+                vm.delete(mContext, name);
+            }
+            mVmsByName.remove(name);
+        }
+    }
+
+    @Nullable
+    @GuardedBy("sCreateLock")
+    private VirtualMachine getVmByName(@NonNull String name) {
+        requireNonNull(name);
+        WeakReference<VirtualMachine> weakReference = mVmsByName.get(name);
+        if (weakReference != null) {
+            VirtualMachine vm = weakReference.get();
+            if (vm != null && vm.getStatus() != VirtualMachine.STATUS_DELETED) {
+                return vm;
+            }
+        }
+        return null;
+    }
+
+    private static final String JSON_SUFFIX = ".json";
+    private static final List<String> SUPPORTED_OS_LIST_FROM_CFG =
+            extractSupportedOSListFromConfig();
+
+    private boolean isVendorModuleEnabled() {
+        return VirtualizationService.nativeIsVendorModulesFlagEnabled();
+    }
+
+    private static List<String> extractSupportedOSListFromConfig() {
+        List<String> supportedOsList = new ArrayList<>();
+        File directory = new File("/apex/com.android.virt/etc");
+        File[] files = directory.listFiles();
+        if (files != null) {
+            for (File file : files) {
+                String fileName = file.getName();
+                if (fileName.endsWith(JSON_SUFFIX)) {
+                    supportedOsList.add(
+                            fileName.substring(0, fileName.length() - JSON_SUFFIX.length()));
+                }
+            }
+        }
+        return supportedOsList;
+    }
+
+    /**
+     * Returns a list of supported OS names.
+     *
+     * @hide
+     */
+    @TestApi
+    @FlaggedApi(Flags.FLAG_AVF_V_TEST_APIS)
+    @NonNull
+    public List<String> getSupportedOSList() throws VirtualMachineException {
+        if (isVendorModuleEnabled()) {
+            return SUPPORTED_OS_LIST_FROM_CFG;
+        } else {
+            return Arrays.asList("microdroid");
+        }
+    }
+
+    /**
+     * Returns {@code true} if given {@code featureName} is enabled.
+     *
+     * @hide
+     */
+    @TestApi
+    @FlaggedApi(Flags.FLAG_AVF_V_TEST_APIS)
+    @RequiresPermission(VirtualMachine.MANAGE_VIRTUAL_MACHINE_PERMISSION)
+    public boolean isFeatureEnabled(@Features String featureName) throws VirtualMachineException {
+        synchronized (sCreateLock) {
+            VirtualizationService service = VirtualizationService.getInstance();
+            try {
+                return service.getBinder().isFeatureEnabled(featureName);
+            } catch (RemoteException e) {
+                throw e.rethrowAsRuntimeException();
+            }
+        }
+    }
+
+    /**
+     * Returns {@code true} if the pVM remote attestation feature is supported. Remote attestation
+     * allows a protected VM to attest its authenticity to a remote server.
+     *
+     * @hide
+     */
+    @TestApi
+    @FlaggedApi(Flags.FLAG_AVF_V_TEST_APIS)
+    @RequiresPermission(VirtualMachine.MANAGE_VIRTUAL_MACHINE_PERMISSION)
+    public boolean isRemoteAttestationSupported() throws VirtualMachineException {
+        synchronized (sCreateLock) {
+            VirtualizationService service = VirtualizationService.getInstance();
+            try {
+                return service.getBinder().isRemoteAttestationSupported();
+            } catch (RemoteException e) {
+                throw e.rethrowAsRuntimeException();
+            }
+        }
+    }
+
+    /**
+     * Returns {@code true} if Updatable VM feature is supported by AVF. Updatable VM allow secrets
+     * and data to be accessible even after updates of boot images and apks. For more info see
+     * packages/modules/Virtualization/docs/updatable_vm.md
+     *
+     * @hide
+     */
+    @TestApi
+    @FlaggedApi(Flags.FLAG_AVF_V_TEST_APIS)
+    @RequiresPermission(VirtualMachine.MANAGE_VIRTUAL_MACHINE_PERMISSION)
+    public boolean isUpdatableVmSupported() throws VirtualMachineException {
+        synchronized (sCreateLock) {
+            VirtualizationService service = VirtualizationService.getInstance();
+            try {
+                return service.getBinder().isUpdatableVmSupported();
+            } catch (RemoteException e) {
+                throw e.rethrowAsRuntimeException();
+            }
+        }
+    }
+}
diff --git a/libs/framework-virtualization/src/android/system/virtualmachine/VirtualizationFrameworkInitializer.java b/libs/framework-virtualization/src/android/system/virtualmachine/VirtualizationFrameworkInitializer.java
new file mode 100644
index 0000000..30ac425
--- /dev/null
+++ b/libs/framework-virtualization/src/android/system/virtualmachine/VirtualizationFrameworkInitializer.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.system.virtualmachine;
+
+import static android.content.pm.PackageManager.FEATURE_VIRTUALIZATION_FRAMEWORK;
+
+import android.annotation.SystemApi;
+import android.app.SystemServiceRegistry;
+import android.content.Context;
+
+/**
+ * Holds initialization code for virtualization module
+ *
+ * @hide
+ */
+@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+public class VirtualizationFrameworkInitializer {
+
+    private VirtualizationFrameworkInitializer() {}
+
+    /**
+     * Called by the static initializer in the {@link SystemServiceRegistry}, and registers {@link
+     * VirtualMachineManager} to the {@link Context}. so that it's accessible from {@link
+     * Context#getSystemService(String)}.
+     */
+    public static void registerServiceWrappers() {
+        // Note: it's important that the getPackageManager().hasSystemFeature() check is executed
+        // in the lambda, and not directly in the registerServiceWrappers method. The
+        // registerServiceWrappers is called during Zygote static initialization, and at that
+        // point the PackageManager is not available yet.
+        //
+        // On the other hand, the lambda is executed after the app calls Context.getSystemService
+        // (VirtualMachineManager.class), at which point the PackageManager is available. The
+        // result of the lambda is cached on per-context basis.
+        SystemServiceRegistry.registerContextAwareService(
+                Context.VIRTUALIZATION_SERVICE,
+                VirtualMachineManager.class,
+                ctx ->
+                        ctx.getPackageManager().hasSystemFeature(FEATURE_VIRTUALIZATION_FRAMEWORK)
+                                ? new VirtualMachineManager(ctx)
+                                : null);
+    }
+}
diff --git a/libs/framework-virtualization/src/android/system/virtualmachine/VirtualizationService.java b/libs/framework-virtualization/src/android/system/virtualmachine/VirtualizationService.java
new file mode 100644
index 0000000..83b64ee
--- /dev/null
+++ b/libs/framework-virtualization/src/android/system/virtualmachine/VirtualizationService.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.system.virtualmachine;
+
+import android.annotation.NonNull;
+import android.os.IBinder;
+import android.os.ParcelFileDescriptor;
+import android.system.virtualizationservice.IVirtualizationService;
+
+import com.android.internal.annotations.GuardedBy;
+
+import java.lang.ref.WeakReference;
+
+/** A running instance of virtmgr that is hosting a VirtualizationService AIDL service. */
+class VirtualizationService {
+    static {
+        System.loadLibrary("virtualizationservice_jni");
+    }
+
+    /* Soft reference caching the last created instance of this class. */
+    @GuardedBy("VirtualMachineManager.sCreateLock")
+    private static WeakReference<VirtualizationService> sInstance;
+
+    /*
+     * Client FD for UDS connection to virtmgr's RpcBinder server. Closing it
+     * will make virtmgr shut down.
+     */
+    private final ParcelFileDescriptor mClientFd;
+
+    /* Persistent connection to IVirtualizationService. */
+    private final IVirtualizationService mBinder;
+
+    private static native int nativeSpawn();
+
+    private native IBinder nativeConnect(int clientFd);
+
+    private native boolean nativeIsOk(int clientFd);
+
+    /*
+     * Retrieve boolean value whether RELEASE_AVF_ENABLE_VENDOR_MODULES build flag is enabled or
+     * not.
+     */
+    static native boolean nativeIsVendorModulesFlagEnabled();
+
+    /*
+     * Spawns a new virtmgr subprocess that will host a VirtualizationService
+     * AIDL service.
+     */
+    private VirtualizationService() throws VirtualMachineException {
+        int clientFd = nativeSpawn();
+        if (clientFd < 0) {
+            throw new VirtualMachineException("Could not spawn Virtualization Manager");
+        }
+        mClientFd = ParcelFileDescriptor.adoptFd(clientFd);
+
+        IBinder binder = nativeConnect(mClientFd.getFd());
+        if (binder == null) {
+            throw new VirtualMachineException("Could not connect to Virtualization Manager");
+        }
+        mBinder = IVirtualizationService.Stub.asInterface(binder);
+    }
+
+    /* Returns the IVirtualizationService binder. */
+    @NonNull
+    IVirtualizationService getBinder() {
+        return mBinder;
+    }
+
+    /*
+     * Checks the state of the client FD. Returns false if the FD is in erroneous state
+     * or if the other endpoint had closed its FD.
+     */
+    private boolean isOk() {
+        return nativeIsOk(mClientFd.getFd());
+    }
+
+    /*
+     * Returns an instance of this class. Might spawn a new instance if one doesn't exist, or
+     * if the previous instance had crashed.
+     */
+    @GuardedBy("VirtualMachineManager.sCreateLock")
+    @NonNull
+    static VirtualizationService getInstance() throws VirtualMachineException {
+        VirtualizationService service = (sInstance == null) ? null : sInstance.get();
+        if (service == null || !service.isOk()) {
+            service = new VirtualizationService();
+            sInstance = new WeakReference<>(service);
+        }
+        return service;
+    }
+}
