Merge changes I9029c90c,I94d731c3

* changes:
  Annotate blocking methods
  Improve API documentation.
diff --git a/javalib/api/system-current.txt b/javalib/api/system-current.txt
index 592a751..30e437b 100644
--- a/javalib/api/system-current.txt
+++ b/javalib/api/system-current.txt
@@ -3,19 +3,19 @@
 
   public class VirtualMachine implements java.lang.AutoCloseable {
     method public void clearCallback();
-    method public void close();
-    method @NonNull 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 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 public android.system.virtualmachine.VirtualMachineConfig getConfig();
-    method @NonNull public java.io.InputStream getConsoleOutput() throws android.system.virtualmachine.VirtualMachineException;
-    method @NonNull public java.io.InputStream getLogOutput() throws android.system.virtualmachine.VirtualMachineException;
+    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 public int getStatus();
-    method @RequiresPermission(android.system.virtualmachine.VirtualMachine.MANAGE_VIRTUAL_MACHINE_PERMISSION) public void run() throws android.system.virtualmachine.VirtualMachineException;
+    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 public android.system.virtualmachine.VirtualMachineConfig setConfig(@NonNull android.system.virtualmachine.VirtualMachineConfig) throws android.system.virtualmachine.VirtualMachineException;
-    method public void stop() throws android.system.virtualmachine.VirtualMachineException;
-    method @NonNull public android.system.virtualmachine.VirtualMachineDescriptor toDescriptor() throws android.system.virtualmachine.VirtualMachineException;
+    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
@@ -91,12 +91,12 @@
   }
 
   public class VirtualMachineManager {
-    method @NonNull @RequiresPermission(android.system.virtualmachine.VirtualMachine.MANAGE_VIRTUAL_MACHINE_PERMISSION) public android.system.virtualmachine.VirtualMachine create(@NonNull String, @NonNull android.system.virtualmachine.VirtualMachineConfig) throws android.system.virtualmachine.VirtualMachineException;
-    method public void delete(@NonNull String) throws android.system.virtualmachine.VirtualMachineException;
-    method @Nullable public android.system.virtualmachine.VirtualMachine get(@NonNull String) throws android.system.virtualmachine.VirtualMachineException;
+    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 public android.system.virtualmachine.VirtualMachine getOrCreate(@NonNull String, @NonNull android.system.virtualmachine.VirtualMachineConfig) throws android.system.virtualmachine.VirtualMachineException;
-    method @NonNull public android.system.virtualmachine.VirtualMachine importFromDescriptor(@NonNull String, @NonNull android.system.virtualmachine.VirtualMachineDescriptor) throws android.system.virtualmachine.VirtualMachineException;
+    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/javalib/src/android/system/virtualmachine/VirtualMachine.java b/javalib/src/android/system/virtualmachine/VirtualMachine.java
index b040cc0..b38e0e4 100644
--- a/javalib/src/android/system/virtualmachine/VirtualMachine.java
+++ b/javalib/src/android/system/virtualmachine/VirtualMachine.java
@@ -52,6 +52,7 @@
 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.res.Configuration;
@@ -108,6 +109,15 @@
  * 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
@@ -512,8 +522,8 @@
             // 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);
         }
+        deleteVmDirectory(context, name);
     }
 
     static void deleteVmDirectory(Context context, String name) throws VirtualMachineException {
@@ -569,13 +579,16 @@
     /**
      * 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; one cannot share its secret to another virtual machine even if they
-     * share the same config. It is also possible that a virtual machine can switch its config,
-     * which can be done by calling {@link #setConfig(VirtualMachineConfig)}.
+     * 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(VirtualMachineConfig)}.
+     *
+     * <p>NOTE: This method may block and should not be called on the main thread.
      *
      * @hide
      */
     @SystemApi
+    @WorkerThread
     @NonNull
     public VirtualMachineConfig getConfig() {
         synchronized (mLock) {
@@ -586,9 +599,12 @@
     /**
      * 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;
@@ -727,11 +743,14 @@
      * registering a callback using {@link #setCallback(Executor, VirtualMachineCallback)} 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) {
@@ -872,10 +891,13 @@
     /**
      * Returns the stream object representing the console output from the virtual machine.
      *
+     * <p>NOTE: This method may block and should not be called on the main thread.
+     *
      * @throws VirtualMachineException if the stream could not be created.
      * @hide
      */
     @SystemApi
+    @WorkerThread
     @NonNull
     public InputStream getConsoleOutput() throws VirtualMachineException {
         synchronized (mLock) {
@@ -887,10 +909,13 @@
     /**
      * Returns the stream object representing the log output from the virtual machine.
      *
+     * <p>NOTE: This method may block and should not be called on the main thread.
+     *
      * @throws VirtualMachineException if the stream could not be created.
      * @hide
      */
     @SystemApi
+    @WorkerThread
     @NonNull
     public InputStream getLogOutput() throws VirtualMachineException {
         synchronized (mLock) {
@@ -904,11 +929,14 @@
      * computer; the machine halts immediately. Software running on the virtual machine is not
      * notified of the event. 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) {
@@ -928,10 +956,13 @@
     /**
      * 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) {
@@ -982,12 +1013,15 @@
      * <p>The new config must be {@link 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 {
@@ -1016,11 +1050,14 @@
      * VirtualMachineCallback#onPayloadReady(VirtualMachine)}, 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)
@@ -1039,10 +1076,13 @@
     /**
      * Opens a vsock connection to the VM on the given port.
      *
+     * <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)
@@ -1088,12 +1128,15 @@
      * 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) {
diff --git a/javalib/src/android/system/virtualmachine/VirtualMachineConfig.java b/javalib/src/android/system/virtualmachine/VirtualMachineConfig.java
index 75e5414..7555dec 100644
--- a/javalib/src/android/system/virtualmachine/VirtualMachineConfig.java
+++ b/javalib/src/android/system/virtualmachine/VirtualMachineConfig.java
@@ -349,9 +349,10 @@
 
     /**
      * Tests if this config is compatible with other config. Being compatible means that the configs
-     * can be interchangeably used for the same virtual machine. Compatible changes includes the
-     * number of CPUs and the size of the RAM. All other changes (e.g. using a different payload,
-     * change of the debug mode, etc.) are considered as incompatible.
+     * 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.
      *
      * @hide
      */
diff --git a/javalib/src/android/system/virtualmachine/VirtualMachineManager.java b/javalib/src/android/system/virtualmachine/VirtualMachineManager.java
index 5b30617..6aa8133 100644
--- a/javalib/src/android/system/virtualmachine/VirtualMachineManager.java
+++ b/javalib/src/android/system/virtualmachine/VirtualMachineManager.java
@@ -24,6 +24,7 @@
 import android.annotation.RequiresFeature;
 import android.annotation.RequiresPermission;
 import android.annotation.SystemApi;
+import android.annotation.WorkerThread;
 import android.content.Context;
 import android.content.pm.PackageManager;
 import android.sysprop.HypervisorProperties;
@@ -123,12 +124,15 @@
      * 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 {
@@ -154,12 +158,15 @@
      * 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.
      * @hide
      */
     @SystemApi
+    @WorkerThread
     @Nullable
     public VirtualMachine get(@NonNull String name) throws VirtualMachineException {
         synchronized (sCreateLock) {
@@ -186,11 +193,14 @@
      *
      * <p>The new virtual machine will be in the same state as the descriptor indicates.
      *
+     * <p>NOTE: This method may block and should not be called on the main thread.
+     *
      * @throws VirtualMachineException if the VM cannot be imported.
      * @hide
      */
     @NonNull
     @SystemApi
+    @WorkerThread
     public VirtualMachine importFromDescriptor(
             @NonNull String name, @NonNull VirtualMachineDescriptor vmDescriptor)
             throws VirtualMachineException {
@@ -205,10 +215,13 @@
      * 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 {
@@ -229,11 +242,14 @@
      * 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);