# Android Virtualization Framework API

These Java APIs allow an app to configure and run a Virtual Machine running
[Microdroid](../../build/microdroid/README.md) and execute native code from the app (the
payload) within it.

There is more information on AVF [here](../../README.md). To see how to package the
payload code that is to run inside a VM, and the native API available to it, see
the [VM Payload API](../libvm_payload/README.md)

The API classes are all in the
[`android.system.virtualmachine`](src/android/system/virtualmachine) package.

All of these APIs were introduced in API level 34 (Android 14). The classes may
not exist in devices running an earlier version.

Note that they are all `@SystemApi` and require the restricted
`android.permission.MANAGE_VIRTUAL_MACHINE` permission, so they are not
available to third party apps. In Android 14 the permission was available only to
privileged apps; in Android 15 it is available to all preinstalled apps. On both
versions it can also be granted to other apps via `adb shell pm grant` for
development purposes.


## Detecting AVF Support

The simplest way to detect whether a device has support for AVF is to retrieve
an instance of the
[`VirtualMachineManager`](src/android/system/virtualmachine/VirtualMachineManager.java)
class; if the result is not `null` then the device has support. You can then
find out whether protected, non-protected VMs, or both are supported using the
`getCapabilities()` method. Note that this code requires API level 34 or higher:

```Java
VirtualMachineManager vmm = context.getSystemService(VirtualMachineManager.class);
if (vmm == null) {
    // AVF is not supported.
} else {
    // AVF is supported.
    int capabilities = vmm.getCapabilities();
    if ((capabilties & CAPABILITY_PROTECTED_VM) != 0) {
        // Protected VMs supported.
    }
    if ((capabilties & CAPABILITY_NON_PROTECTED_VM) != 0) {
        // Non-Protected VMs supported.
    }
}
```

An alternative for detecting AVF support is to query support for the
`android.software.virtualization_framework` system feature. This method will
work on any API level, and return false if it is below 34:

```Java
if (getPackageManager().hasSystemFeature(PackageManager.FEATURE_VIRTUALIZATION_FRAMEWORK)) {
    // AVF is supported.
}
```

You can also express a dependency on this system feature in your app's manifest
with a
[`<uses-feature>`](https://developer.android.com/guide/topics/manifest/uses-feature-element)
element.


## Starting a VM

Once you have an instance of the
[`VirtualMachineManager`](src/android/system/virtualmachine/VirtualMachineManager.java),
a VM can be started by:
- Specifying the desired VM configuration, using a
  [`VirtualMachineConfig`](src/android/system/virtualmachine/VirtualMachineConfig.java)
  builder;
- Creating a new
  [`VirtualMachine`](src/android/system/virtualmachine/VirtualMachine.java)
  instance (or retrieving an existing one);
- Registering to retrieve events from the VM by providing a
  [`VirtualMachineCallback`](src/android/system/virtualmachine/VirtualMachineCallback.java)
  (optional, but recommended);
- Running the VM.

A minimal example might look like this:

```Java
VirtualMachineConfig config =
        new VirtualMachineConfig.Builder(this)
            .setProtectedVm(true)
            .setPayloadBinaryName("my_payload.so")
            .build();

VirtualMachine vm = vmm.getOrCreate("my vm", config);

vm.setCallback(executor, new VirtualMachineCallback() {...});

vm.run();
```

Here we are running a protected VM, which will execute the code in the
`my_payload.so` file included in your APK.

Information about the VM, including its configuration, is stored in files in
your app's private data directory. The file names are based on the VM name you
supply. So once an instance of a VM has been created it can be retrieved by name
even if the app is restarted or the device is rebooted. Directly inspecting or
modifying these files is not recommended.

The `getOrCreate()` call will retrieve an existing VM instance if it exists (in
which case the `config` parameter is ignored), or create a new one
otherwise. There are also separate `get()` and `create()` methods.

The `run()` method is asynchronous; it returns successfully once the VM is
starting. You can find out when the VM is ready, or if it fails, via your
`VirtualMachineCallback` implementation.

## VM Configuration

There are other things that you can specify as part of the
[`VirtualMachineConfig`](src/android/system/virtualmachine/VirtualMachineConfig.java):
- Whether the VM should be debuggable. A debuggable VM is not secure, but it
  does allow access to logs from inside the VM, which can be useful for
  troubleshooting.
- How much memory should be available to the VM. (This is an upper bound;
  typically memory is allocated to the VM as it is needed until the limit is
  reached - but there is some overhead proportional to the maximum size.)
- How many virtual CPUs the VM has.
- How much encrypted storage the VM has.
- The path to the installed APK containing the code to run as the VM
  payload. (Normally you don't need this; the APK path is determined from the
  context passed to the config builder.)

## VM Life-cycle

To find out the progress of the Virtual Machine once it is started you should
implement the methods defined by
[`VirtualMachineCallback`](src/android/system/virtualmachine/VirtualMachineCallback.java). These
are called when the following events happen:
- `onPayloadStarted()`: The VM payload is about to be run.
- `onPayloadReady()`: The VM payload is running and ready to accept
  connections. (This notification is triggered by the payload code, using the
  [`AVmPayload_notifyPayloadReady()`](../libs/libvm_payload/include/vm_payload.h)
  function.)
- `onPayloadFinished()`: The VM payload has exited normally. The exit code of
  the VM (the value returned by [`AVmPayload_main()`](../libs/libvm_payload/README.md))
  is supplied as a parameter.
- `onError()`: The VM failed; something went wrong. An error code and
  human-readable message are provided which may help diagnosing the problem.
- `onStopped()`: The VM is no longer running. This is the final notification
  from any VM run, whether or not it was successful. You can run the VM again
  when you want to. A reason code indicating why the VM stopped is supplied as a
  parameter.

You can also query the status of a VM at any point by calling `getStatus()` on
the `VirtualMachine` object. This will return one of the following values:
- `STATUS_STOPPED`: The VM is not running - either it has not yet been started,
  or it stopped after running.
- `STATUS_RUNNING`: The VM is running. Your payload inside the VM may not be
  running, since the VM may be in the process of starting or stopping.
- `STATUS_DELETED`: The VM has been deleted, e.g. by calling the `delete()`
  method on
  [`VirtualMachineManager`](src/android/system/virtualmachine/VirtualMachineManager.java). This
  is irreversible - once a VM is in this state it will never leave it.

Some methods on
[`VirtualMachine`](src/android/system/virtualmachine/VirtualMachine.java) can
only be called when the VM status is `STATUS_RUNNING` (e.g. `stop()`), and some
can only be called when the it is `STATUS_STOPPED` (e.g. `run()`).

## VM Identity and Secrets

Every VM has a 32-byte secret unique to it, which is not available to the
host. We refer to this as the VM identity.  The secret, and thus the identity,
doesn’t normally change if the same VM is stopped and started, even after a
reboot.

In Android 14 the secret is derived, using the [Open Profile for
DICE](https://pigweed.googlesource.com/open-dice/+/refs/heads/main/docs/android.md),
from:
- A device-specific randomly generated value;
- The complete system image;
- A per-instance salt;
- The code running in the VM, including the bootloader, kernel, Microdroid and
  payload;
- Significant VM configuration options, e.g.  whether the VM is debuggable.

Any change to any of these will mean a different secret is generated.  So while
an attacker could start a similar VM with maliciously altered code, that VM will
not have access to the same secret. An attempt to start an existing VM instance
which doesn't derive the same secret will fail.

However, this also means that if the payload code changes - for example, your
app is updated - then this also changes the identity. An existing VM instance
will no longer be runnable, and you will have to delete it and create a new
instance with a new secret.

The payload code is not given direct access to the VM secret, but an API is
provided to allow deterministically deriving further secrets from it,
e.g. encryption or signing keys. See
[`AVmPayload_getVmInstanceSecret()`](../libs/libvm_payload/include/vm_payload.h).

Some VM configuration changes are allowed that don’t affect the identity -
e.g. changing the number of CPUs or the amount of memory allocated to the
VM. This can be done using the `setConfig()` method on
[`VirtualMachine`](src/android/system/virtualmachine/VirtualMachine.java).

Deleting a VM (using the `delete()` method on
[`VirtualMachineManager`](src/android/system/virtualmachine/VirtualMachineManager.java))
and recreating it will generate a new salt, so the new VM will have a different
secret, even if it is otherwise identical.

## Communicating with a VM

Once the VM payload has successfully started you will probably want to establish
communication between it and your app.

Only the app that started a VM can connect to it. The VM can accept connections
from the app, but cannot initiate connections to other VMs or other processes in
the host Android.

### Vsock

The simplest form of communication is using a socket running over the
[vsock](https://man7.org/linux/man-pages/man7/vsock.7.html) protocol.

We suggest that the VM payload should create a listening socket (using the
standard socket API) and then trigger the `onPayloadReady()` callback; the app
can then connect to the socket. This helps to avoid a race condition where the
app tries to connect before the VM is listening, necessitating a retry
mechanism.

In the payload this might look like this:

```C++
#include "vm_payload.h"

extern "C" int AVmPayload_main() {
  int fd = socket(AF_VSOCK, SOCK_STREAM, 0);
  // bind, listen
  AVmPayload_notifyPayloadReady();
  // accept, read/write, ...
}
```

And, in the app, like this:

```Java
void onPayloadReady(VirtualMachine vm) {
  ParcelFileDescriptor pfd = vm.connectVsock(port);
  // ...
}
```

Vsock is useful for simple communication, or transferring of bulk data. For a
richer RPC style of communication we suggest using Binder.

### Binder

The use of AIDL interfaces between the VM and app is supported via Binder RPC,
which transmits messages over an underlying vsock socket.

Note that Binder RPC has some limitations compared to the kernel Binder used in
Android - for example file descriptors can't be sent. It also isn't possible to
send a kernel Binder interface over Binder RPC, or vice versa.

There is a payload API to allow an AIDL interface to be served over a specific
vsock port, and the VirtualMachine class provides a way to connect to the VM and
retrieve an instance of the interface.

The payload code to serve a hypothetical `IPayload` interface might look like
this:

```C++
class PayloadImpl : public BnPayload { ... };


extern "C" int AVmPayload_main() {
  auto service = ndk::SharedRefBase::make<PayloadImpl>();
  auto callback = [](void*) {
    AVmPayload_notifyPayloadReady();
  };
  AVmPayload_runVsockRpcServer(service->asBinder().get(),
    port, callback, nullptr);
}

```

And then the app code to connect to it could look like this:

```Java
void onPayloadReady(VirtualMachine vm) {
  IPayload payload =
    Payload.Stub.asInterface(vm.connectToVsockServer(port));
  // ...
}
```

## Stopping a VM

You can stop a VM abruptly by calling the `stop()` method on the
[`VirtualMachine`](src/android/system/virtualmachine/VirtualMachine.java)
instance. This is equivalent to turning off the power; the VM gets no
opportunity to clean up at all. Any unwritten data might be lost.

A better strategy might be to wait for the VM to exit cleanly (e.g. waiting for
the `onStopped()` callback).

Then you can arrange for your VM payload code to exit when it has finished its
task (by returning from [`AVmPayload_main()`](../libs/libvm_payload/README.md), or
calling `exit()`). Alternatively you could exit when you receive a request to do
so from the app, e.g. via binder.

When the VM payload does this you will receive an `onPayloadFinished()`
callback, if you have installed a
[`VirtualMachineCallback`](src/android/system/virtualmachine/VirtualMachineCallback.java),
which includes the payload's exit code.

Use of `stop()` should be reserved as a recovery mechanism - for example if the
VM has not stopped within a reasonable time (a few seconds, say) after being
requested to.

The status of a VM will be `STATUS_STOPPED` if your `onStopped()` callback is
invoked, or after a successful call to `stop()`. Note that your `onStopped()`
will be called on the VM even if it ended as a result of a call to `stop()`.

# Encrypted Storage

When configuring a VM you can specify that it should have access to an encrypted
storage filesystem of up to a specified size, using the
`setEncryptedStorageBytes()` method on a
[`VirtualMachineConfig`](src/android/system/virtualmachine/VirtualMachineConfig.java)
builder.

Inside the VM this storage is mounted at a path that can be retrieved via the
[`AVmPayload_getEncryptedStoragePath()`](../libs/libvm_payload/include/vm_payload.h)
function. The VM can create sub-directories and read and write files here. Any
data written is persisted and should be available next time the VM is run. (An
automatic sync is done when the payload exits normally.)

Outside the VM the storage is persisted as a file in the app’s private data
directory. The data is encrypted using a key derived from the VM secret, which
is not made available outside the VM.

So an attacker should not be able to decrypt the data; however, a sufficiently
powerful attacker could delete it, wholly or partially roll it back to an
earlier version, or modify it, corrupting the data.

For more info see [README](https://cs.android.com/android/platform/superproject/main/+/main:packages/modules/Virtualization/libs/framework-virtualization/README.md)

# Transferring a VM

It is possible to make a copy of a VM instance. This can be used to transfer a
VM from one app to another, which can be useful in some circumstances.

This should only be done while the VM is stopped. The first step is to call
`toDescriptor()` on the
[`VirtualMachine`](src/android/system/virtualmachine/VirtualMachine.java)
instance, which returns a
[`VirtualMachineDescriptor`](src/android/system/virtualmachine/VirtualMachineDescriptor.java)
object. This object internally contains open file descriptors to the files that
hold the VM's state (its instance data, configuration, and encrypted storage).

A `VirtualMachineDescriptor` is
[`Parcelable`](https://developer.android.com/reference/android/os/Parcelable),
so it can be passed to another app via a Binder call.  Any app with a
`VirtualMachineDescriptor` can pass it, along with a new VM name, to the
`importFromDescriptor()` method on
[`VirtualMachineManager`](src/android/system/virtualmachine/VirtualMachineManager.java). This
is equivalent to calling `create()` with the same name and configuration, except
that the new VM is the same instance as the original, with the same VM secret,
and has access to a copy of the original's encrypted storage.

Once the transfer has been completed it would be reasonable to delete the
original VM, using the `delete()` method on `VirtualMachineManager`.





