Close() shouldn't throw
Close() should handle releasing resources when we are no longer using
a VM (since we implement autoCloseable). It shouldn't throw if th VM
is stopped - that just means nothing is being used.
We could get rid of stop(), or give it the same semantics, but I think
it has uses - if the app should be running then stop() throwing shows
something is wrong.
Add tests. Also minor gratuitous simplification in benchmark code.
Bug: 258397314
Test: atest MicrodroidTests
Change-Id: Ia8a6661ba1664368ba7f09ed0e4dcb8b39469fb8
diff --git a/javalib/api/system-current.txt b/javalib/api/system-current.txt
index 850bffc..16995c5 100644
--- a/javalib/api/system-current.txt
+++ b/javalib/api/system-current.txt
@@ -3,7 +3,7 @@
public class VirtualMachine implements java.lang.AutoCloseable {
method public void clearCallback();
- method public void close() throws android.system.virtualmachine.VirtualMachineException;
+ method public void close();
method @NonNull public android.os.IBinder connectToVsockServer(int) throws android.system.virtualmachine.VirtualMachineException;
method @NonNull public android.os.ParcelFileDescriptor connectVsock(int) throws android.system.virtualmachine.VirtualMachineException;
method public int getCid() throws android.system.virtualmachine.VirtualMachineException;
diff --git a/javalib/src/android/system/virtualmachine/VirtualMachine.java b/javalib/src/android/system/virtualmachine/VirtualMachine.java
index 193d213..dec873f 100644
--- a/javalib/src/android/system/virtualmachine/VirtualMachine.java
+++ b/javalib/src/android/system/virtualmachine/VirtualMachine.java
@@ -65,6 +65,7 @@
import android.system.virtualizationservice.VirtualMachineAppConfig;
import android.system.virtualizationservice.VirtualMachineState;
import android.util.JsonReader;
+import android.util.Log;
import com.android.internal.annotations.GuardedBy;
@@ -105,6 +106,8 @@
*/
@SystemApi
public class VirtualMachine implements AutoCloseable {
+ 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";
@@ -754,7 +757,8 @@
* 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()}.
*
- * @throws VirtualMachineException if the virtual machine could not be stopped.
+ * @throws VirtualMachineException if the virtual machine is not running or could not be
+ * stopped.
* @hide
*/
@SystemApi
@@ -775,15 +779,31 @@
}
/**
- * Stops this virtual machine. See {@link #stop()}.
+ * Stops this virtual machine, if it is running.
*
- * @throws VirtualMachineException if the virtual machine could not be stopped.
+ * @see #stop()
* @hide
*/
@SystemApi
@Override
- public void close() throws VirtualMachineException {
- stop();
+ public void close() {
+ synchronized (mLock) {
+ if (mVirtualMachine == null) {
+ return;
+ }
+ try {
+ if (stateToStatus(mVirtualMachine.getState()) == STATUS_RUNNING) {
+ mVirtualMachine.stop();
+ mVirtualMachine = null;
+ }
+ } 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 {