Drop the VM reference when stopped

A VM may exit even without a call to stop() or close(). When we notice
that, drop our reference to the binder interface (to allow GC to kick
in abd VS to exit) and drop our memory pressure callback.

This is mostly good housekeeping, but it also makes sure we don't end
up registering the callback multiple times if we call run() again on
the same VM without an intervening stop().

Bug: 238931615
Test: atest MicrodroidTests
Change-Id: If4c75ca11adf4239e4337405c24ff5db08707e7a
diff --git a/javalib/src/android/system/virtualmachine/VirtualMachine.java b/javalib/src/android/system/virtualmachine/VirtualMachine.java
index c061003..1cf808a 100644
--- a/javalib/src/android/system/virtualmachine/VirtualMachine.java
+++ b/javalib/src/android/system/virtualmachine/VirtualMachine.java
@@ -610,9 +610,22 @@
         } catch (RemoteException e) {
             throw e.rethrowAsRuntimeException();
         }
+        // It's stopped, but we still have a reference to it - we can fix that.
+        dropVm();
     }
 
-    // If we have an IVirtualMachine in the running state return it, otherwise throw.
+    /**
+     * 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 {
@@ -879,8 +892,7 @@
             }
             try {
                 mVirtualMachine.stop();
-                mContext.unregisterComponentCallbacks(mMemoryManagementCallbacks);
-                mVirtualMachine = null;
+                dropVm();
             } catch (RemoteException e) {
                 throw e.rethrowAsRuntimeException();
             } catch (ServiceSpecificException e) {
@@ -905,8 +917,7 @@
             try {
                 if (stateToStatus(mVirtualMachine.getState()) == STATUS_RUNNING) {
                     mVirtualMachine.stop();
-                    mContext.unregisterComponentCallbacks(mMemoryManagementCallbacks);
-                    mVirtualMachine = null;
+                    dropVm();
                 }
             } catch (RemoteException e) {
                 throw e.rethrowAsRuntimeException();