Implement platform API to assign devices

Clients can specify either device types or sysfs nodes when creating a
VM. The app should have USE_CUSTOM_VIRTUAL_MACHINE permission to do so.

Bug: 287379025
Test: TH
Test: adb root && adb shell /apex/com.android.virt/bin/vm \
      run-microdroid --devices /sys/bus/platform/devices/16d00000.eh \
      --protected
Change-Id: I375d455fa1fa9cbad6e552cdb7b3e9a2138f9278
diff --git a/virtualizationservice/aidl/android/system/virtualizationservice/VirtualMachineAppConfig.aidl b/virtualizationservice/aidl/android/system/virtualizationservice/VirtualMachineAppConfig.aidl
index 2b762c4..9021055 100644
--- a/virtualizationservice/aidl/android/system/virtualizationservice/VirtualMachineAppConfig.aidl
+++ b/virtualizationservice/aidl/android/system/virtualizationservice/VirtualMachineAppConfig.aidl
@@ -108,6 +108,9 @@
 
         /** A disk image containing vendor specific modules. */
         @nullable ParcelFileDescriptor vendorImage;
+
+        /** List of SysFS nodes of devices to be assigned */
+        String[] devices;
     }
 
     /** Configuration parameters guarded by android.permission.USE_CUSTOM_VIRTUAL_MACHINE */
diff --git a/virtualizationservice/aidl/android/system/virtualizationservice/VirtualMachineRawConfig.aidl b/virtualizationservice/aidl/android/system/virtualizationservice/VirtualMachineRawConfig.aidl
index 87d4ba2..7c0ed0c 100644
--- a/virtualizationservice/aidl/android/system/virtualizationservice/VirtualMachineRawConfig.aidl
+++ b/virtualizationservice/aidl/android/system/virtualizationservice/VirtualMachineRawConfig.aidl
@@ -69,4 +69,7 @@
      * If set to zero, then gdb server won't be started.
      */
     int gdbPort = 0;
+
+    /** List of SysFS nodes of devices to be assigned */
+    String[] devices;
 }
diff --git a/virtualizationservice/src/aidl.rs b/virtualizationservice/src/aidl.rs
index 2dbb6e2..8aea556 100644
--- a/virtualizationservice/src/aidl.rs
+++ b/virtualizationservice/src/aidl.rs
@@ -37,7 +37,7 @@
 use libc::VMADDR_CID_HOST;
 use log::{error, info, warn};
 use rustutils::system_properties;
-use std::collections::{HashMap, HashSet};
+use std::collections::HashMap;
 use std::fs::{canonicalize, create_dir, remove_dir_all, set_permissions, File, Permissions};
 use std::io::{Read, Write};
 use std::os::fd::FromRawFd;
@@ -188,16 +188,7 @@
     fn bindDevicesToVfioDriver(&self, devices: &[String]) -> binder::Result<ParcelFileDescriptor> {
         check_use_custom_virtual_machine()?;
 
-        let mut set = HashSet::new();
-        for device in devices.iter() {
-            if !set.insert(device) {
-                return Err(Status::new_exception_str(
-                    ExceptionCode::ILLEGAL_ARGUMENT,
-                    Some(format!("duplicated device {device}")),
-                ));
-            }
-            bind_device(device)?;
-        }
+        devices.iter().try_for_each(|x| bind_device(x))?;
 
         // TODO(b/278008182): create a file descriptor containing DTBO for devices.
         let (raw_read, raw_write) = pipe2(OFlag::O_CLOEXEC).map_err(|e| {
diff --git a/virtualizationservice/src/rkpvm.rs b/virtualizationservice/src/rkpvm.rs
index ebfb667..63160f4 100644
--- a/virtualizationservice/src/rkpvm.rs
+++ b/virtualizationservice/src/rkpvm.rs
@@ -76,8 +76,8 @@
         memoryMib: 300,
         cpuTopology: CpuTopology::ONE_CPU,
         platformVersion: "~1.0".to_string(),
-        taskProfiles: vec![],
         gdbPort: 0, // No gdb
+        ..Default::default()
     });
     let vm = VmInstance::create(service.as_ref(), &config, None, None, None, None)
         .context("Failed to create service VM")?;