virtmgr: Support dumping guest DT for debugging

Give a way to make crosvm dump the guest DT it generated without needing
to recompile and/or reinstall any part of the stack, by detecting the
newly-introduced boolean system property

    hypervisor.virtualizationmanager.dump_device_tree

which can be set on devices being debugged.
Note: this propery is redundant if you pass a path to dump the device
tree using --dump-device-tree

Bug: 335160369
Test: m virtmgr && TH
Test: adb shell setprop
hypervisor.virtualizationmanager.dump_device_tree true && /apex/.../vm
run-microdroid && check
/data/misc/virtualizationservice/CID/device_tree.dtb exists

Change-Id: I71ba56f14812ccb9bc5dab1ad3789656aa9a8460
diff --git a/android/virtmgr/src/aidl.rs b/android/virtmgr/src/aidl.rs
index 87d7a88..4555ebc 100644
--- a/android/virtmgr/src/aidl.rs
+++ b/android/virtmgr/src/aidl.rs
@@ -534,7 +534,13 @@
             clone_or_prepare_logger_fd(console_out_fd, format!("Console({})", cid))?;
         let console_in_fd = console_in_fd.map(clone_file).transpose()?;
         let log_fd = clone_or_prepare_logger_fd(log_fd, format!("Log({})", cid))?;
-        let dump_dt_fd = dump_dt_fd.map(clone_file).transpose()?;
+        let dump_dt_fd = if let Some(fd) = dump_dt_fd {
+            Some(clone_file(fd)?)
+        } else if debug_config.dump_device_tree {
+            Some(prepare_dump_dt_file(&temporary_directory)?)
+        } else {
+            None
+        };
 
         // Counter to generate unique IDs for temporary image files.
         let mut next_temporary_image_id = 0;
@@ -1669,6 +1675,16 @@
     Ok(ramdump)
 }
 
+/// Create the empty device tree dump file
+fn prepare_dump_dt_file(temporary_directory: &Path) -> binder::Result<File> {
+    let path = temporary_directory.join("device_tree.dtb");
+    let file = File::create(path)
+        .context("Failed to prepare device tree dump file")
+        .with_log()
+        .or_service_specific_exception(-1)?;
+    Ok(file)
+}
+
 fn is_protected(config: &VirtualMachineConfig) -> bool {
     match config {
         VirtualMachineConfig::RawConfig(config) => config.protectedVm,