diff --git a/java/Android.bp b/java/Android.bp
new file mode 100644
index 0000000..1c55f78
--- /dev/null
+++ b/java/Android.bp
@@ -0,0 +1,24 @@
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+soong_config_module_type {
+    name: "avf_flag_aware_android_app",
+    module_type: "android_app",
+    config_namespace: "ANDROID",
+    bool_variables: ["release_avf_allow_preinstalled_apps"],
+    properties: ["manifest"],
+}
+
+// Defines our permissions
+avf_flag_aware_android_app {
+    name: "android.system.virtualmachine.res",
+    installable: true,
+    apex_available: ["com.android.virt"],
+    platform_apis: true,
+    soong_config_variables: {
+        release_avf_allow_preinstalled_apps: {
+            manifest: "AndroidManifestNext.xml",
+        },
+    },
+}
diff --git a/java/AndroidManifest.xml b/java/AndroidManifest.xml
new file mode 100644
index 0000000..95b9cfa
--- /dev/null
+++ b/java/AndroidManifest.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * 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.
+ -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+  package="com.android.virtualmachine.res">
+
+  <!-- @SystemApi Allows an application to create and run a Virtual Machine
+       using the Virtualization Framework APIs
+       (android.system.virtualmachine.*).
+       <p>Protection level: signature|privileged|development
+       @hide
+  -->
+  <permission android:name="android.permission.MANAGE_VIRTUAL_MACHINE"
+      android:protectionLevel="signature|privileged|development" />
+
+  <!-- @hide Allows an application to run a Virtual Machine with a custom
+       kernel or a Microdroid configuration file.
+       <p>Not for use by third-party applications.
+  -->
+  <permission android:name="android.permission.USE_CUSTOM_VIRTUAL_MACHINE"
+      android:protectionLevel="signature|development" />
+
+  <!-- @hide Allows an application to access various Virtual Machine debug
+       facilities, e.g. list all running VMs.
+       <p>Not for use by third-party applications.
+  -->
+  <permission android:name="android.permission.DEBUG_VIRTUAL_MACHINE"
+      android:protectionLevel="signature" />
+
+  <application android:hasCode="false" />
+</manifest>
diff --git a/java/AndroidManifestNext.xml b/java/AndroidManifestNext.xml
new file mode 100644
index 0000000..ebcb8ba
--- /dev/null
+++ b/java/AndroidManifestNext.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * 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.
+ -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+  package="com.android.virtualmachine.res">
+
+  <!-- @SystemApi Allows an application to create and run a Virtual Machine
+       using the Virtualization Framework APIs
+       (android.system.virtualmachine.*).
+       <p>Protection level: signature|preinstalled|development
+       @hide
+  -->
+  <permission android:name="android.permission.MANAGE_VIRTUAL_MACHINE"
+      android:protectionLevel="signature|preinstalled|development" />
+
+  <!-- @hide Allows an application to run a Virtual Machine with a custom
+       kernel or a Microdroid configuration file.
+       <p>Not for use by third-party applications.
+  -->
+  <permission android:name="android.permission.USE_CUSTOM_VIRTUAL_MACHINE"
+      android:protectionLevel="signature|development" />
+
+  <!-- @hide Allows an application to access various Virtual Machine debug
+       facilities, e.g. list all running VMs.
+       <p>Not for use by third-party applications.
+  -->
+  <permission android:name="android.permission.DEBUG_VIRTUAL_MACHINE"
+      android:protectionLevel="signature" />
+
+  <application android:hasCode="false" />
+</manifest>
diff --git a/java/framework/Android.bp b/java/framework/Android.bp
new file mode 100644
index 0000000..32b2aee
--- /dev/null
+++ b/java/framework/Android.bp
@@ -0,0 +1,46 @@
+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__",
+    ],
+}
diff --git a/java/framework/README.md b/java/framework/README.md
new file mode 100644
index 0000000..cf7a6cb
--- /dev/null
+++ b/java/framework/README.md
@@ -0,0 +1,371 @@
+# Android Virtualization Framework API
+
+These Java APIs allow an app to configure and run a Virtual Machine running
+[Microdroid](../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](../vm_payload/README.md)
+
+The API classes are all in the
+[`android.system.virtualmachine`](src/android/system/virtualmachine) package.
+
+Note that these APIs are all `@SystemApi` and require the restricted
+`android.permission.MANAGE_VIRTUAL_MACHINE` permission, so they are not
+available to third party apps.
+
+All of these APIs were introduced in API level 34 (Android 14). The classes may
+not exist in devices running an earlier version.
+
+## 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()`](../vm_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()`](../vm_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()`](../vm_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()`](../vm_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()`](../vm_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.
+
+# 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/java/framework/api/current.txt b/java/framework/api/current.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/java/framework/api/current.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/java/framework/api/module-lib-current.txt b/java/framework/api/module-lib-current.txt
new file mode 100644
index 0000000..4d59764
--- /dev/null
+++ b/java/framework/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/java/framework/api/module-lib-removed.txt b/java/framework/api/module-lib-removed.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/java/framework/api/module-lib-removed.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/java/framework/api/removed.txt b/java/framework/api/removed.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/java/framework/api/removed.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/java/framework/api/system-current.txt b/java/framework/api/system-current.txt
new file mode 100644
index 0000000..d9bafa1
--- /dev/null
+++ b/java/framework/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/java/framework/api/system-removed.txt b/java/framework/api/system-removed.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/java/framework/api/system-removed.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/java/framework/api/test-current.txt b/java/framework/api/test-current.txt
new file mode 100644
index 0000000..3cd8e42
--- /dev/null
+++ b/java/framework/api/test-current.txt
@@ -0,0 +1,36 @@
+// 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") @Nullable public String getOs();
+    method @Nullable public String getPayloadConfigPath();
+    method public boolean isVmConsoleInputSupported();
+  }
+
+  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;
+    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 @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/java/framework/api/test-removed.txt b/java/framework/api/test-removed.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/java/framework/api/test-removed.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/java/framework/jarjar-rules.txt b/java/framework/jarjar-rules.txt
new file mode 100644
index 0000000..726f9aa
--- /dev/null
+++ b/java/framework/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/java/framework/src/android/system/virtualmachine/VirtualMachine.java b/java/framework/src/android/system/virtualmachine/VirtualMachine.java
new file mode 100644
index 0000000..6b03cfe
--- /dev/null
+++ b/java/framework/src/android/system/virtualmachine/VirtualMachine.java
@@ -0,0 +1,1505 @@
+/*
+ * 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.FlaggedApi;
+import android.annotation.CallbackExecutor;
+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.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.MemoryTrimLevel;
+import android.system.virtualizationservice.PartitionType;
+import android.system.virtualizationservice.VirtualMachineAppConfig;
+import android.system.virtualizationservice.VirtualMachineState;
+import android.util.JsonReader;
+import android.util.Log;
+
+import com.android.internal.annotations.GuardedBy;
+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.InputStreamReader;
+import java.io.OutputStream;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.nio.channels.FileChannel;
+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.Collections;
+import java.util.List;
+import java.util.concurrent.Executor;
+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/+/master:packages/modules/Virtualization/vm_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;
+
+    /**
+     * 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 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;
+
+    /**
+     * 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) {
+            @MemoryTrimLevel int vmTrimLevel;
+
+            switch (level) {
+                case ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL:
+                    vmTrimLevel = MemoryTrimLevel.TRIM_MEMORY_RUNNING_CRITICAL;
+                    break;
+                case ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW:
+                    vmTrimLevel = MemoryTrimLevel.TRIM_MEMORY_RUNNING_LOW;
+                    break;
+                case ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE:
+                    vmTrimLevel = MemoryTrimLevel.TRIM_MEMORY_RUNNING_MODERATE;
+                    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. */
+                    vmTrimLevel = MemoryTrimLevel.TRIM_MEMORY_RUNNING_CRITICAL;
+                    break;
+                default:
+                    /* Treat unrecognised messages as generic low-memory warnings. */
+                    vmTrimLevel = MemoryTrimLevel.TRIM_MEMORY_RUNNING_LOW;
+                    break;
+            }
+
+            synchronized (mLock) {
+                try {
+                    if (mVirtualMachine != null) {
+                        mVirtualMachine.onTrimMemory(vmTrimLevel);
+                    }
+                } 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;
+
+    @NonNull 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;
+
+    /** 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 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);
+        mInstanceFilePath = new File(thisVmDir, INSTANCE_IMAGE_FILE);
+        mIdsigFilePath = new File(thisVmDir, IDSIG_FILE);
+        mExtraApks = setupExtraApks(context, config, thisVmDir);
+        mMemoryManagementCallbacks = new MemoryManagementCallbacks();
+        mContext = context;
+        mEncryptedStoreFilePath =
+                (config.isEncryptedStorageEnabled())
+                        ? new File(thisVmDir, ENCRYPTED_STORE_FILE)
+                        : null;
+
+        mVmOutputCaptured = config.isVmOutputCaptured();
+        mVmConsoleInputSupported = config.isVmConsoleInputSupported();
+    }
+
+    /**
+     * 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());
+                }
+            }
+            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 (IOException 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();
+
+            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 {
+                deleteRecursively(vmDir);
+            } catch (IOException 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.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;
+        }
+        deleteVmDirectory(context, name);
+    }
+
+    static void deleteVmDirectory(Context context, String name) throws VirtualMachineException {
+        try {
+            deleteRecursively(getVmDir(context, name));
+        } catch (IOException e) {
+            throw new VirtualMachineException(e);
+        }
+    }
+
+    @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() {
+        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);
+        }
+    }
+
+    /**
+     * 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()}.
+     *
+     * <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 (mVmOutputCaptured) {
+                    createVmOutputPipes();
+                }
+
+                if (mVmConsoleInputSupported) {
+                    createVmInputPipes();
+                }
+
+                VirtualMachineConfig vmConfig = getConfig();
+                VirtualMachineAppConfig appConfig =
+                        vmConfig.toVsConfig(mContext.getPackageManager());
+                appConfig.name = mName;
+
+                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 {
+                    createIdSigs(service, appConfig);
+                } catch (FileNotFoundException e) {
+                    throw new VirtualMachineException("Failed to generate APK signature", e);
+                }
+
+                android.system.virtualizationservice.VirtualMachineConfig vmConfigParcel =
+                        android.system.virtualizationservice.VirtualMachineConfig.appConfig(
+                                appConfig);
+
+                mVirtualMachine =
+                        service.createVm(
+                                vmConfigParcel, mConsoleOutWriter, mConsoleInReader, mLogWriter);
+                mVirtualMachine.registerCallback(new CallbackTranslator(service));
+                mContext.registerComponentCallbacks(mMemoryManagementCallbacks);
+                mVirtualMachine.start();
+            } catch (IllegalStateException | ServiceSpecificException e) {
+                throw new VirtualMachineException(e);
+            } catch (RemoteException e) {
+                throw e.rethrowAsRuntimeException();
+            }
+        }
+    }
+
+    private void createIdSigs(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);
+        appConfig.instanceImage = ParcelFileDescriptor.open(mInstanceFilePath, MODE_READ_WRITE);
+        if (mEncryptedStoreFilePath != null) {
+            appConfig.encryptedStorageImage =
+                    ParcelFileDescriptor.open(mEncryptedStoreFilePath, MODE_READ_WRITE);
+        }
+        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) {
+                ParcelFileDescriptor[] pipe = ParcelFileDescriptor.createPipe();
+                mConsoleInReader = pipe[0];
+                mConsoleInWriter = pipe[1];
+            }
+        } catch (IOException e) {
+            throw new VirtualMachineException("Failed to create input stream for VM", e);
+        }
+    }
+
+    /**
+     * 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();
+            } 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),
+                        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/payload/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 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;
+            }
+        }
+    }
+}
diff --git a/java/framework/src/android/system/virtualmachine/VirtualMachineCallback.java b/java/framework/src/android/system/virtualmachine/VirtualMachineCallback.java
new file mode 100644
index 0000000..d72ba14
--- /dev/null
+++ b/java/framework/src/android/system/virtualmachine/VirtualMachineCallback.java
@@ -0,0 +1,157 @@
+/*
+ * 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/java/framework/src/android/system/virtualmachine/VirtualMachineConfig.java b/java/framework/src/android/system/virtualmachine/VirtualMachineConfig.java
new file mode 100644
index 0000000..693a7d7
--- /dev/null
+++ b/java/framework/src/android/system/virtualmachine/VirtualMachineConfig.java
@@ -0,0 +1,1033 @@
+/*
+ * 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 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.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.VirtualMachineAppConfig;
+import android.system.virtualizationservice.VirtualMachinePayloadConfig;
+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.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 = {};
+
+    // These define the schema of the config file persisted on disk.
+    private static final int VERSION = 8;
+    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_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_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_VENDOR_DISK_IMAGE_PATH = "vendorDiskImagePath";
+    private static final String KEY_OS = "os";
+    private static final String KEY_EXTRA_APKS = "extraApks";
+
+    /** @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;
+
+    /**
+     * 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 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;
+
+    @Nullable private final File mVendorDiskImage;
+
+    /** OS name of the VM using payload binaries. null if the VM uses a payload config file. */
+    @Nullable private final String mOs;
+
+    private VirtualMachineConfig(
+            @Nullable String packageName,
+            @Nullable String apkPath,
+            List<String> extraApks,
+            @Nullable String payloadConfigPath,
+            @Nullable String payloadBinaryName,
+            @DebugLevel int debugLevel,
+            boolean protectedVm,
+            long memoryBytes,
+            @CpuTopology int cpuTopology,
+            long encryptedStorageBytes,
+            boolean vmOutputCaptured,
+            boolean vmConsoleInputSupported,
+            @Nullable File vendorDiskImage,
+            @Nullable String os) {
+        // 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;
+        mDebugLevel = debugLevel;
+        mProtectedVm = protectedVm;
+        mMemoryBytes = memoryBytes;
+        mCpuTopology = cpuTopology;
+        mEncryptedStorageBytes = encryptedStorageBytes;
+        mVmOutputCaptured = vmOutputCaptured;
+        mVmConsoleInputSupported = vmConsoleInputSupported;
+        mVendorDiskImage = vendorDiskImage;
+        mOs = os;
+    }
+
+    /** 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);
+        if (payloadConfigPath == null) {
+            builder.setPayloadBinaryName(b.getString(KEY_PAYLOADBINARYNAME));
+        } else {
+            builder.setPayloadConfigPath(payloadConfigPath);
+        }
+
+        @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));
+        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));
+
+        String vendorDiskImagePath = b.getString(KEY_VENDOR_DISK_IMAGE_PATH);
+        if (vendorDiskImagePath != null) {
+            builder.setVendorDiskImage(new File(vendorDiskImagePath));
+        }
+
+        String os = b.getString(KEY_OS);
+        if (os != null) {
+            builder.setOs(os);
+        }
+
+        String[] extraApks = b.getStringArray(KEY_EXTRA_APKS);
+        if (extraApks != null) {
+            for (String extraApk : extraApks) {
+                builder.addExtraApk(extraApk);
+            }
+        }
+
+        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);
+        b.putInt(KEY_DEBUGLEVEL, mDebugLevel);
+        b.putBoolean(KEY_PROTECTED_VM, mProtectedVm);
+        b.putInt(KEY_CPU_TOPOLOGY, mCpuTopology);
+        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);
+        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.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 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 the OS of the VM using a payload binary. Returns null if the VM uses payload config.
+     *
+     * @see Builder#setOs
+     * @hide
+     */
+    @TestApi
+    @FlaggedApi(Flags.FLAG_AVF_V_TEST_APIS)
+    @Nullable
+    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.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);
+    }
+
+    /**
+     * 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.osName = mOs;
+            payloadConfig.extraApks = Collections.emptyList();
+            vsConfig.payload =
+                    VirtualMachineAppConfig.Payload.payloadConfig(payloadConfig);
+        } else {
+            vsConfig.payload =
+                    VirtualMachineAppConfig.Payload.configPath(mPayloadConfigPath);
+        }
+        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;
+        }
+        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 {
+        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 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;
+        private long mEncryptedStorageBytes;
+        private boolean mVmOutputCaptured = false;
+        private boolean mVmConsoleInputSupported = false;
+        @Nullable private File mVendorDiskImage;
+        @Nullable private String mOs;
+
+        /**
+         * 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");
+            }
+
+            String os = null;
+            if (mPayloadBinaryName == null) {
+                if (mPayloadConfigPath == null) {
+                    throw new IllegalStateException("setPayloadBinaryName must be called");
+                }
+                if (mOs != null) {
+                    throw new IllegalStateException(
+                            "setPayloadConfigPath and setOs may not both 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 (mOs != null) {
+                    os = mOs;
+                } else {
+                    os = DEFAULT_OS;
+                }
+            }
+
+            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");
+            }
+
+            return new VirtualMachineConfig(
+                    packageName,
+                    apkPath,
+                    mExtraApks,
+                    mPayloadConfigPath,
+                    mPayloadBinaryName,
+                    mDebugLevel,
+                    mProtectedVm,
+                    mMemoryBytes,
+                    mCpuTopology,
+                    mEncryptedStorageBytes,
+                    mVmOutputCaptured,
+                    mVmConsoleInputSupported,
+                    mVendorDiskImage,
+                    os);
+        }
+
+        /**
+         * 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/microdroid/payload/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 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) {
+            if (payloadBinaryName.contains(File.separator)) {
+                throw new IllegalArgumentException(
+                        "Invalid binary file name: " + payloadBinaryName);
+            }
+            mPayloadBinaryName =
+                    requireNonNull(payloadBinaryName, "payloadBinaryName must not be null");
+            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 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 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 String os) {
+            mOs = requireNonNull(os, "os must not be null");
+            return this;
+        }
+    }
+}
diff --git a/java/framework/src/android/system/virtualmachine/VirtualMachineDescriptor.java b/java/framework/src/android/system/virtualmachine/VirtualMachineDescriptor.java
new file mode 100644
index 0000000..710925d
--- /dev/null
+++ b/java/framework/src/android/system/virtualmachine/VirtualMachineDescriptor.java
@@ -0,0 +1,143 @@
+/*
+ * 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;
+    @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(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 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,
+            @NonNull ParcelFileDescriptor instanceImgFd,
+            @Nullable ParcelFileDescriptor encryptedStoreFd) {
+        mConfigFd = requireNonNull(configFd);
+        mInstanceImgFd = requireNonNull(instanceImgFd);
+        mEncryptedStoreFd = encryptedStoreFd;
+    }
+
+    private VirtualMachineDescriptor(Parcel in) {
+        mConfigFd = requireNonNull(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;
+                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/java/framework/src/android/system/virtualmachine/VirtualMachineException.java b/java/framework/src/android/system/virtualmachine/VirtualMachineException.java
new file mode 100644
index 0000000..9948fda
--- /dev/null
+++ b/java/framework/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/java/framework/src/android/system/virtualmachine/VirtualMachineManager.java b/java/framework/src/android/system/virtualmachine/VirtualMachineManager.java
new file mode 100644
index 0000000..5020ff0
--- /dev/null
+++ b/java/framework/src/android/system/virtualmachine/VirtualMachineManager.java
@@ -0,0 +1,396 @@
+/*
+ * 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.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.ref.WeakReference;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 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_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 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 {
+        synchronized (sCreateLock) {
+            VirtualMachine 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.deleteVmDirectory(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;
+    }
+
+    /**
+     * Returns a list of supported OS names.
+     *
+     * @hide
+     */
+    @TestApi
+    @FlaggedApi(Flags.FLAG_AVF_V_TEST_APIS)
+    @NonNull
+    public List<String> getSupportedOSList() throws VirtualMachineException {
+        synchronized (sCreateLock) {
+            VirtualizationService service = VirtualizationService.getInstance();
+            try {
+                return Arrays.asList(service.getBinder().getSupportedOSList());
+            } catch (RemoteException e) {
+                throw e.rethrowAsRuntimeException();
+            }
+        }
+    }
+
+    /**
+     * Returns {@code true} if given {@code featureName} is enabled.
+     *
+     * @hide
+     */
+    @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();
+            }
+        }
+    }
+}
diff --git a/java/framework/src/android/system/virtualmachine/VirtualizationFrameworkInitializer.java b/java/framework/src/android/system/virtualmachine/VirtualizationFrameworkInitializer.java
new file mode 100644
index 0000000..30ac425
--- /dev/null
+++ b/java/framework/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/java/framework/src/android/system/virtualmachine/VirtualizationService.java b/java/framework/src/android/system/virtualmachine/VirtualizationService.java
new file mode 100644
index 0000000..57990a9
--- /dev/null
+++ b/java/framework/src/android/system/virtualmachine/VirtualizationService.java
@@ -0,0 +1,99 @@
+/*
+ * 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);
+
+    /*
+     * 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;
+    }
+}
diff --git a/java/jni/Android.bp b/java/jni/Android.bp
new file mode 100644
index 0000000..74a1766
--- /dev/null
+++ b/java/jni/Android.bp
@@ -0,0 +1,36 @@
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+cc_library_shared {
+    name: "libvirtualizationservice_jni",
+    defaults: ["avf_build_flags_cc"],
+    srcs: [
+        "android_system_virtualmachine_VirtualizationService.cpp",
+    ],
+    apex_available: ["com.android.virt"],
+    shared_libs: [
+        "libbase",
+        "libbinder_ndk",
+        "libbinder_rpc_unstable",
+        "liblog",
+        "libnativehelper",
+    ],
+}
+
+cc_library_shared {
+    name: "libvirtualmachine_jni",
+    defaults: ["avf_build_flags_cc"],
+    srcs: [
+        "android_system_virtualmachine_VirtualMachine.cpp",
+    ],
+    apex_available: ["com.android.virt"],
+    shared_libs: [
+        "android.system.virtualizationservice-ndk",
+        "libbase",
+        "libbinder_ndk",
+        "libbinder_rpc_unstable",
+        "liblog",
+        "libnativehelper",
+    ],
+}
diff --git a/java/jni/android_system_virtualmachine_VirtualMachine.cpp b/java/jni/android_system_virtualmachine_VirtualMachine.cpp
new file mode 100644
index 0000000..b3354cc
--- /dev/null
+++ b/java/jni/android_system_virtualmachine_VirtualMachine.cpp
@@ -0,0 +1,67 @@
+/*
+ * Copyright 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.
+ */
+
+#define LOG_TAG "VirtualMachine"
+
+#include <aidl/android/system/virtualizationservice/IVirtualMachine.h>
+#include <android/binder_auto_utils.h>
+#include <android/binder_ibinder_jni.h>
+#include <jni.h>
+#include <log/log.h>
+
+#include <binder_rpc_unstable.hpp>
+#include <tuple>
+
+#include "common.h"
+
+extern "C" JNIEXPORT jobject JNICALL
+Java_android_system_virtualmachine_VirtualMachine_nativeConnectToVsockServer(
+        JNIEnv* env, [[maybe_unused]] jclass clazz, jobject vmBinder, jint port) {
+    using aidl::android::system::virtualizationservice::IVirtualMachine;
+    using ndk::ScopedFileDescriptor;
+    using ndk::SpAIBinder;
+
+    auto vm = IVirtualMachine::fromBinder(SpAIBinder{AIBinder_fromJavaBinder(env, vmBinder)});
+
+    std::tuple args{env, vm.get(), port};
+    using Args = decltype(args);
+
+    auto requestFunc = [](void* param) {
+        auto [env, vm, port] = *static_cast<Args*>(param);
+
+        ScopedFileDescriptor fd;
+        if (auto status = vm->connectVsock(port, &fd); !status.isOk()) {
+            env->ThrowNew(env->FindClass("android/system/virtualmachine/VirtualMachineException"),
+                          ("Failed to connect vsock: " + status.getDescription()).c_str());
+            return -1;
+        }
+
+        // take ownership
+        int ret = fd.get();
+        *fd.getR() = -1;
+
+        return ret;
+    };
+
+    RpcSessionHandle session;
+    // We need a thread pool to be able to support linkToDeath, or callbacks
+    // (b/268335700). These threads are currently created eagerly, so we don't
+    // want too many. The number 1 is chosen after some discussion, and to match
+    // the server-side default (mMaxThreads on RpcServer).
+    ARpcSession_setMaxIncomingThreads(session.get(), 1);
+    auto client = ARpcSession_setupPreconnectedClient(session.get(), requestFunc, &args);
+    return AIBinder_toJavaBinder(env, client);
+}
diff --git a/java/jni/android_system_virtualmachine_VirtualizationService.cpp b/java/jni/android_system_virtualmachine_VirtualizationService.cpp
new file mode 100644
index 0000000..fbd1fd5
--- /dev/null
+++ b/java/jni/android_system_virtualmachine_VirtualizationService.cpp
@@ -0,0 +1,103 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "VirtualizationService"
+
+#include <android-base/unique_fd.h>
+#include <android/binder_ibinder_jni.h>
+#include <jni.h>
+#include <log/log.h>
+#include <poll.h>
+
+#include <string>
+
+#include "common.h"
+
+using namespace android::base;
+
+static constexpr const char VIRTMGR_PATH[] = "/apex/com.android.virt/bin/virtmgr";
+static constexpr size_t VIRTMGR_THREADS = 2;
+
+extern "C" JNIEXPORT jint JNICALL
+Java_android_system_virtualmachine_VirtualizationService_nativeSpawn(
+        JNIEnv* env, [[maybe_unused]] jclass clazz) {
+    unique_fd serverFd, clientFd;
+    if (!Socketpair(SOCK_STREAM, &serverFd, &clientFd)) {
+        env->ThrowNew(env->FindClass("android/system/virtualmachine/VirtualMachineException"),
+                      ("Failed to create socketpair: " + std::string(strerror(errno))).c_str());
+        return -1;
+    }
+
+    unique_fd waitFd, readyFd;
+    if (!Pipe(&waitFd, &readyFd, 0)) {
+        env->ThrowNew(env->FindClass("android/system/virtualmachine/VirtualMachineException"),
+                      ("Failed to create pipe: " + std::string(strerror(errno))).c_str());
+        return -1;
+    }
+
+    if (fork() == 0) {
+        // Close client's FDs.
+        clientFd.reset();
+        waitFd.reset();
+
+        auto strServerFd = std::to_string(serverFd.get());
+        auto strReadyFd = std::to_string(readyFd.get());
+
+        execl(VIRTMGR_PATH, VIRTMGR_PATH, "--rpc-server-fd", strServerFd.c_str(), "--ready-fd",
+              strReadyFd.c_str(), NULL);
+    }
+
+    // Close virtmgr's FDs.
+    serverFd.reset();
+    readyFd.reset();
+
+    // Wait for the server to signal its readiness by closing its end of the pipe.
+    char buf;
+    if (read(waitFd.get(), &buf, sizeof(buf)) < 0) {
+        env->ThrowNew(env->FindClass("android/system/virtualmachine/VirtualMachineException"),
+                      "Failed to wait for VirtualizationService to be ready");
+        return -1;
+    }
+
+    return clientFd.release();
+}
+
+extern "C" JNIEXPORT jobject JNICALL
+Java_android_system_virtualmachine_VirtualizationService_nativeConnect(JNIEnv* env,
+                                                                       [[maybe_unused]] jobject obj,
+                                                                       int clientFd) {
+    RpcSessionHandle session;
+    ARpcSession_setFileDescriptorTransportMode(session.get(),
+                                               ARpcSession_FileDescriptorTransportMode::Unix);
+    ARpcSession_setMaxIncomingThreads(session.get(), VIRTMGR_THREADS);
+    // SAFETY - ARpcSession_setupUnixDomainBootstrapClient does not take ownership of clientFd.
+    auto client = ARpcSession_setupUnixDomainBootstrapClient(session.get(), clientFd);
+    return AIBinder_toJavaBinder(env, client);
+}
+
+extern "C" JNIEXPORT jboolean JNICALL
+Java_android_system_virtualmachine_VirtualizationService_nativeIsOk(JNIEnv* env,
+                                                                    [[maybe_unused]] jobject obj,
+                                                                    int clientFd) {
+    /* Setting events=0 only returns POLLERR, POLLHUP or POLLNVAL. */
+    struct pollfd pfds[] = {{.fd = clientFd, .events = 0}};
+    if (poll(pfds, /*nfds*/ 1, /*timeout*/ 0) < 0) {
+        env->ThrowNew(env->FindClass("android/system/virtualmachine/VirtualMachineException"),
+                      ("Failed to poll client FD: " + std::string(strerror(errno))).c_str());
+        return false;
+    }
+    return pfds[0].revents == 0;
+}
diff --git a/java/jni/common.h b/java/jni/common.h
new file mode 100644
index 0000000..c70ba76
--- /dev/null
+++ b/java/jni/common.h
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+
+#include <binder_rpc_unstable.hpp>
+
+// Wrapper around ARpcSession handle that automatically frees the handle when
+// it goes out of scope.
+class RpcSessionHandle {
+public:
+    RpcSessionHandle() : mHandle(ARpcSession_new()) {}
+    ~RpcSessionHandle() { ARpcSession_free(mHandle); }
+
+    ARpcSession* get() { return mHandle; }
+
+private:
+    ARpcSession* mHandle;
+};
diff --git a/java/service/Android.bp b/java/service/Android.bp
new file mode 100644
index 0000000..9c1fa01
--- /dev/null
+++ b/java/service/Android.bp
@@ -0,0 +1,30 @@
+// 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 {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+java_library {
+    name: "service-virtualization",
+    srcs: [
+        "src/**/*.java",
+    ],
+    defaults: [
+        "framework-system-server-module-defaults",
+    ],
+    sdk_version: "system_server_current",
+    apex_available: ["com.android.virt"],
+    installable: true,
+}
diff --git a/java/service/src/com/android/system/virtualmachine/VirtualizationSystemService.java b/java/service/src/com/android/system/virtualmachine/VirtualizationSystemService.java
new file mode 100644
index 0000000..2905acd
--- /dev/null
+++ b/java/service/src/com/android/system/virtualmachine/VirtualizationSystemService.java
@@ -0,0 +1,31 @@
+/*
+ * 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 com.android.system.virtualmachine;
+
+import android.content.Context;
+import com.android.server.SystemService;
+
+/** TODO */
+public class VirtualizationSystemService extends SystemService {
+
+    public VirtualizationSystemService(Context context) {
+        super(context);
+    }
+
+    @Override
+    public void onStart() {}
+}
