Pass dt symbol argument for devices to crosvm

For crosvm to amend device tree for assigned devices, vendors provide
information about vm dtbo node.

Bug: 297313212
Test: vm run-microdroid and see crosvm argument
Change-Id: I52bc532361a40a0db6c1b6b0b25cc3ef29886f48
diff --git a/virtualizationservice/src/aidl.rs b/virtualizationservice/src/aidl.rs
index 645a82b..ed5c513 100644
--- a/virtualizationservice/src/aidl.rs
+++ b/virtualizationservice/src/aidl.rs
@@ -28,6 +28,7 @@
     AtomVmCreationRequested::AtomVmCreationRequested,
     AtomVmExited::AtomVmExited,
     IGlobalVmContext::{BnGlobalVmContext, IGlobalVmContext},
+    IVirtualizationServiceInternal::BoundDevice::BoundDevice,
     IVirtualizationServiceInternal::IVirtualizationServiceInternal,
     IVfioHandler::{BpVfioHandler, IVfioHandler},
 };
@@ -179,44 +180,14 @@
     fn getAssignableDevices(&self) -> binder::Result<Vec<AssignableDevice>> {
         check_use_custom_virtual_machine()?;
 
-        let mut ret = Vec::new();
-        let xml_path = Path::new("/vendor/etc/avf/assignable_devices.xml");
-        if !xml_path.exists() {
-            return Ok(ret);
-        }
-
-        let xml = fs::read(xml_path)
-            .context("Failed to read assignable_devices.xml")
-            .with_log()
-            .or_service_specific_exception(-1)?;
-
-        let xml = String::from_utf8(xml)
-            .context("assignable_devices.xml is not a valid UTF-8 file")
-            .with_log()
-            .or_service_specific_exception(-1)?;
-
-        let devices: Devices = serde_xml_rs::from_str(&xml)
-            .context("can't parse assignable_devices.xml")
-            .with_log()
-            .or_service_specific_exception(-1)?;
-
-        let mut device_set = HashSet::new();
-
-        for device in devices.device.into_iter() {
-            if device_set.contains(&device.sysfs_path) {
-                warn!("duplicated assignable device {device:?}; ignoring...")
-            } else if Path::new(&device.sysfs_path).exists() {
-                device_set.insert(device.sysfs_path.clone());
-                ret.push(AssignableDevice { kind: device.kind, node: device.sysfs_path });
-            } else {
-                warn!("assignable device {device:?} doesn't exist; ignoring...");
-            }
-        }
-
-        Ok(ret)
+        Ok(get_assignable_devices()?
+            .device
+            .into_iter()
+            .map(|x| AssignableDevice { node: x.sysfs_path, kind: x.kind })
+            .collect::<Vec<_>>())
     }
 
-    fn bindDevicesToVfioDriver(&self, devices: &[String]) -> binder::Result<()> {
+    fn bindDevicesToVfioDriver(&self, devices: &[String]) -> binder::Result<Vec<BoundDevice>> {
         check_use_custom_virtual_machine()?;
 
         let vfio_service: Strong<dyn IVfioHandler> =
@@ -233,7 +204,17 @@
             vfio_service.writeVmDtbo(&ParcelFileDescriptor::new(dtbo))?;
         }
 
-        Ok(())
+        Ok(get_assignable_devices()?
+            .device
+            .into_iter()
+            .filter_map(|x| {
+                if devices.contains(&x.sysfs_path) {
+                    Some(BoundDevice { sysfsPath: x.sysfs_path, dtboNode: x.dtbo_node })
+                } else {
+                    None
+                }
+            })
+            .collect::<Vec<_>>())
     }
 }
 
@@ -241,14 +222,54 @@
 #[derive(Debug, Deserialize)]
 struct Device {
     kind: String,
+    dtbo_node: String,
     sysfs_path: String,
 }
 
-#[derive(Debug, Deserialize)]
+#[derive(Debug, Default, Deserialize)]
 struct Devices {
     device: Vec<Device>,
 }
 
+fn get_assignable_devices() -> binder::Result<Devices> {
+    let xml_path = Path::new("/vendor/etc/avf/assignable_devices.xml");
+    if !xml_path.exists() {
+        return Ok(Devices { ..Default::default() });
+    }
+
+    let xml = fs::read(xml_path)
+        .context("Failed to read assignable_devices.xml")
+        .with_log()
+        .or_service_specific_exception(-1)?;
+
+    let xml = String::from_utf8(xml)
+        .context("assignable_devices.xml is not a valid UTF-8 file")
+        .with_log()
+        .or_service_specific_exception(-1)?;
+
+    let mut devices: Devices = serde_xml_rs::from_str(&xml)
+        .context("can't parse assignable_devices.xml")
+        .with_log()
+        .or_service_specific_exception(-1)?;
+
+    let mut device_set = HashSet::new();
+    devices.device.retain(move |device| {
+        if device_set.contains(&device.sysfs_path) {
+            warn!("duplicated assignable device {device:?}; ignoring...");
+            return false;
+        }
+
+        if !Path::new(&device.sysfs_path).exists() {
+            warn!("assignable device {device:?} doesn't exist; ignoring...");
+            return false;
+        }
+
+        device_set.insert(device.sysfs_path.clone());
+        true
+    });
+    Ok(devices)
+}
+
 #[derive(Debug, Default)]
 struct GlobalVmInstance {
     /// The unique CID assigned to the VM for vsock communication.