libavf: Add AVirtualMachineRawConfig_setDeviceTreeOverlay

Bug: 381971307
Test: T/H
Change-Id: I44bc5281edce0e3933ed122708814fddd4122067
diff --git a/libs/libavf/src/lib.rs b/libs/libavf/src/lib.rs
index 9ae2635..4f23da4 100644
--- a/libs/libavf/src/lib.rs
+++ b/libs/libavf/src/lib.rs
@@ -23,7 +23,7 @@
 
 use android_system_virtualizationservice::{
     aidl::android::system::virtualizationservice::{
-        CpuTopology::CpuTopology, DiskImage::DiskImage,
+        AssignedDevices::AssignedDevices, CpuTopology::CpuTopology, DiskImage::DiskImage,
         IVirtualizationService::IVirtualizationService, VirtualMachineConfig::VirtualMachineConfig,
         VirtualMachineRawConfig::VirtualMachineRawConfig,
     },
@@ -263,6 +263,32 @@
     -libc::ENOTSUP
 }
 
+/// Add device tree overlay blob
+///
+/// # Safety
+/// `config` must be a pointer returned by `AVirtualMachineRawConfig_create`. `fd` must be a valid
+/// file descriptor or -1. `AVirtualMachineRawConfig_setDeviceTreeOverlay` takes ownership of `fd`
+/// and `fd` will be closed upon `AVirtualMachineRawConfig_delete`.
+#[no_mangle]
+pub unsafe extern "C" fn AVirtualMachineRawConfig_setDeviceTreeOverlay(
+    config: *mut VirtualMachineRawConfig,
+    fd: c_int,
+) {
+    // SAFETY: `config` is assumed to be a valid, non-null pointer returned by
+    // AVirtualMachineRawConfig_create. It's the only reference to the object.
+    let config = unsafe { &mut *config };
+
+    match get_file_from_fd(fd) {
+        Some(file) => {
+            let fd = ParcelFileDescriptor::new(file);
+            config.devices = AssignedDevices::Dtbo(Some(fd));
+        }
+        _ => {
+            config.devices = Default::default();
+        }
+    };
+}
+
 /// Spawn a new instance of `virtmgr`, a child process that will host the `VirtualizationService`
 /// AIDL service, and connect to the child process.
 ///