Add VM ref holding to Virt Manager

So as to support running VMs from `adb shell` without a persistent
session (closing the shell), add two new methods to Virt Manager AIDL:
debugVmHoldRef and debugVmDropRef. The former will accept a strong VM
reference from the user and store it inside Virt Manager. The latter
can be used to retrieve the reference by CID and will make Virt Manager
drop it. Both are limited to the shell user.

On the `vm` tool side, a new '-d/--daemonize' flag is added to the
'vm run' command which calls debugVmHoldRef after a VM is created and
exits. 'vm stop <cid>' command is added to allow killing a previously
daemonized VM.

Bug: 182254712
Test: vm run -d <json>; vm list; vm drop <cid>
Change-Id: Ic7198b3fc7a19688fca762ec04dd2430a7626222
diff --git a/vm/src/main.rs b/vm/src/main.rs
index 34031f7..329c859 100644
--- a/vm/src/main.rs
+++ b/vm/src/main.rs
@@ -42,6 +42,15 @@
         /// Path to VM config JSON
         #[structopt(parse(from_os_str))]
         config: PathBuf,
+
+        /// Detach VM from the terminal and run in the background
+        #[structopt(short, long)]
+        daemonize: bool,
+    },
+    /// Stop a virtual machine running in the background
+    Stop {
+        /// CID of the virtual machine
+        cid: u32,
     },
     /// List running virtual machines
     List,
@@ -58,24 +67,44 @@
         .context("Failed to find Virt Manager service")?;
 
     match opt {
-        Opt::Run { config } => command_run(virt_manager, &config),
+        Opt::Run { config, daemonize } => command_run(virt_manager, &config, daemonize),
+        Opt::Stop { cid } => command_stop(virt_manager, cid),
         Opt::List => command_list(virt_manager),
     }
 }
 
 /// Run a VM from the given configuration file.
-fn command_run(virt_manager: Strong<dyn IVirtManager>, config_path: &PathBuf) -> Result<(), Error> {
+fn command_run(
+    virt_manager: Strong<dyn IVirtManager>,
+    config_path: &PathBuf,
+    daemonize: bool,
+) -> Result<(), Error> {
     let config_filename = config_path.to_str().context("Failed to parse VM config path")?;
     let stdout_file = ParcelFileDescriptor::new(duplicate_stdout()?);
-    let vm =
-        virt_manager.startVm(config_filename, Some(&stdout_file)).context("Failed to start VM")?;
+    let stdout = if daemonize { None } else { Some(&stdout_file) };
+    let vm = virt_manager.startVm(config_filename, stdout).context("Failed to start VM")?;
+
     let cid = vm.getCid().context("Failed to get CID")?;
     println!("Started VM from {} with CID {}.", config_filename, cid);
 
-    // Wait until the VM dies. If we just returned immediately then the IVirtualMachine Binder
-    // object would be dropped and the VM would be killed.
-    wait_for_death(&mut vm.as_binder())?;
-    println!("VM died");
+    if daemonize {
+        // Pass the VM reference back to Virt Manager and have it hold it in the background.
+        virt_manager.debugHoldVmRef(&*vm).context("Failed to pass VM to Virt Manager")
+    } else {
+        // Wait until the VM dies. If we just returned immediately then the IVirtualMachine Binder
+        // object would be dropped and the VM would be killed.
+        wait_for_death(&mut vm.as_binder())?;
+        println!("VM died");
+        Ok(())
+    }
+}
+
+/// Retrieve reference to a previously daemonized VM and stop it.
+fn command_stop(virt_manager: Strong<dyn IVirtManager>, cid: u32) -> Result<(), Error> {
+    virt_manager
+        .debugDropVmRef(cid as i32)
+        .context("Failed to get VM from Virt Manager")?
+        .context("CID does not correspond to a running background VM")?;
     Ok(())
 }