Merge changes I68639dec,Ic48a707c into main
* changes:
Add InputDevice in VirtualMachineRawConfig
Add paravirtualized_devices config
diff --git a/Android.bp b/Android.bp
index 7cedfb7..9734cba 100644
--- a/Android.bp
+++ b/Android.bp
@@ -30,6 +30,7 @@
"release_avf_enable_remote_attestation",
"release_avf_enable_vendor_modules",
"release_avf_enable_virt_cpufreq",
+ "release_avf_support_custom_vm_with_paravirtualized_devices",
],
properties: [
"cfgs",
@@ -60,6 +61,9 @@
release_avf_enable_virt_cpufreq: {
cfgs: ["virt_cpufreq"],
},
+ release_avf_support_custom_vm_with_paravirtualized_devices: {
+ cfgs: ["paravirtualized_devices"],
+ },
},
}
diff --git a/java/framework/src/android/system/virtualmachine/VirtualMachineConfig.java b/java/framework/src/android/system/virtualmachine/VirtualMachineConfig.java
index a8f318c..d267763 100644
--- a/java/framework/src/android/system/virtualmachine/VirtualMachineConfig.java
+++ b/java/framework/src/android/system/virtualmachine/VirtualMachineConfig.java
@@ -40,6 +40,7 @@
import android.sysprop.HypervisorProperties;
import android.system.virtualizationservice.DiskImage;
import android.system.virtualizationservice.Partition;
+import android.system.virtualizationservice.InputDevice;
import android.system.virtualizationservice.VirtualMachineAppConfig;
import android.system.virtualizationservice.VirtualMachinePayloadConfig;
import android.system.virtualizationservice.VirtualMachineRawConfig;
@@ -650,6 +651,7 @@
config.cpuTopology = (byte) this.mCpuTopology;
config.devices = EMPTY_STRING_ARRAY;
config.platformVersion = "~1.0";
+ config.inputDevices = new InputDevice[0];
return config;
}
diff --git a/virtualizationmanager/src/aidl.rs b/virtualizationmanager/src/aidl.rs
index 279b4ec..1f3fb4a 100644
--- a/virtualizationmanager/src/aidl.rs
+++ b/virtualizationmanager/src/aidl.rs
@@ -17,7 +17,7 @@
use crate::{get_calling_pid, get_calling_uid};
use crate::atom::{write_vm_booted_stats, write_vm_creation_stats};
use crate::composite::make_composite_image;
-use crate::crosvm::{CrosvmConfig, DiskFile, DisplayConfig, PayloadState, VmContext, VmInstance, VmState};
+use crate::crosvm::{CrosvmConfig, DiskFile, DisplayConfig, InputDeviceOption, PayloadState, VmContext, VmInstance, VmState};
use crate::debug_config::DebugConfig;
use crate::dt_overlay::{create_device_tree_overlay, VM_DT_OVERLAY_MAX_SIZE, VM_DT_OVERLAY_PATH};
use crate::payload::{add_microdroid_payload_images, add_microdroid_system_images, add_microdroid_vendor_image};
@@ -32,6 +32,7 @@
AssignableDevice::AssignableDevice,
CpuTopology::CpuTopology,
DiskImage::DiskImage,
+ InputDevice::InputDevice,
IVirtualMachine::{BnVirtualMachine, IVirtualMachine},
IVirtualMachineCallback::IVirtualMachineCallback,
IVirtualizationService::IVirtualizationService,
@@ -581,13 +582,27 @@
} else {
(vec![], None)
};
+ let display_config = if cfg!(paravirtualized_devices) {
+ config
+ .displayConfig
+ .as_ref()
+ .map(DisplayConfig::new)
+ .transpose()
+ .or_binder_exception(ExceptionCode::ILLEGAL_ARGUMENT)?
+ } else {
+ None
+ };
- let display_config = config
- .displayConfig
- .as_ref()
- .map(DisplayConfig::new)
- .transpose()
- .or_binder_exception(ExceptionCode::ILLEGAL_ARGUMENT)?;
+ let input_device_options = if cfg!(paravirtualized_devices) {
+ config
+ .inputDevices
+ .iter()
+ .map(to_input_device_option_from)
+ .collect::<Result<Vec<InputDeviceOption>, _>>()
+ .or_binder_exception(ExceptionCode::ILLEGAL_ARGUMENT)?
+ } else {
+ vec![]
+ };
// Actually start the VM.
let crosvm_config = CrosvmConfig {
@@ -615,6 +630,7 @@
dtbo,
device_tree_overlay,
display_config,
+ input_device_options,
};
let instance = Arc::new(
VmInstance::new(
@@ -720,6 +736,23 @@
(result / granularity) * granularity
}
+fn to_input_device_option_from(input_device: &InputDevice) -> Result<InputDeviceOption> {
+ Ok(match input_device {
+ InputDevice::SingleTouch(single_touch) => InputDeviceOption::SingleTouch {
+ file: clone_file(single_touch.pfd.as_ref().ok_or(anyhow!("pfd should have value"))?)?,
+ height: u32::try_from(single_touch.height)?,
+ width: u32::try_from(single_touch.width)?,
+ name: if !single_touch.name.is_empty() {
+ Some(single_touch.name.clone())
+ } else {
+ None
+ },
+ },
+ InputDevice::EvDev(evdev) => InputDeviceOption::EvDev(clone_file(
+ evdev.pfd.as_ref().ok_or(anyhow!("pfd should have value"))?,
+ )?),
+ })
+}
/// Given the configuration for a disk image, assembles the `DiskFile` to pass to crosvm.
///
/// This may involve assembling a composite disk from a set of partition images.
diff --git a/virtualizationmanager/src/crosvm.rs b/virtualizationmanager/src/crosvm.rs
index 86c9af3..2e4c517 100644
--- a/virtualizationmanager/src/crosvm.rs
+++ b/virtualizationmanager/src/crosvm.rs
@@ -120,6 +120,7 @@
pub dtbo: Option<File>,
pub device_tree_overlay: Option<File>,
pub display_config: Option<DisplayConfig>,
+ pub input_device_options: Vec<InputDeviceOption>,
}
#[derive(Debug)]
@@ -154,6 +155,14 @@
pub writable: bool,
}
+/// virtio-input device configuration from `external/crosvm/src/crosvm/config.rs`
+#[derive(Debug)]
+#[allow(dead_code)]
+pub enum InputDeviceOption {
+ EvDev(File),
+ SingleTouch { file: File, width: u32, height: u32, name: Option<String> },
+}
+
type VfioDevice = Strong<dyn IBoundDevice>;
/// The lifecycle state which the payload in the VM has reported itself to be in.
@@ -955,14 +964,34 @@
if let Some(dt_overlay) = &config.device_tree_overlay {
command.arg("--device-tree-overlay").arg(add_preserved_fd(&mut preserved_fds, dt_overlay));
}
- if let Some(display_config) = &config.display_config {
- command.arg("--gpu")
- // TODO(b/331708504): support backend config as well
- .arg("backend=virglrenderer,context-types=virgl2,egl=true,surfaceless=true,glx=false,gles=true")
- .arg(format!("--gpu-display=mode=windowed[{},{}],dpi=[{},{}],refresh-rate={}", display_config.width, display_config.height, display_config.horizontal_dpi, display_config.vertical_dpi, display_config.refresh_rate))
- .arg(format!("--android-display-service={}", config.name));
+
+ if cfg!(paravirtualized_devices) {
+ if let Some(display_config) = &config.display_config {
+ command.arg("--gpu")
+ // TODO(b/331708504): support backend config as well
+ .arg("backend=virglrenderer,context-types=virgl2,egl=true,surfaceless=true,glx=false,gles=true")
+ .arg(format!("--gpu-display=mode=windowed[{},{}],dpi=[{},{}],refresh-rate={}", display_config.width, display_config.height, display_config.horizontal_dpi, display_config.vertical_dpi, display_config.refresh_rate))
+ .arg(format!("--android-display-service={}", config.name));
+ }
}
+ if cfg!(paravirtualized_devices) {
+ for input_device_option in config.input_device_options.iter() {
+ command.arg("--input");
+ command.arg(match input_device_option {
+ InputDeviceOption::EvDev(file) => {
+ format!("evdev[path={}]", add_preserved_fd(&mut preserved_fds, file))
+ }
+ InputDeviceOption::SingleTouch { file, width, height, name } => format!(
+ "single-touch[path={},width={},height={}{}]",
+ add_preserved_fd(&mut preserved_fds, file),
+ width,
+ height,
+ name.as_ref().map_or("".into(), |n| format!(",name={}", n))
+ ),
+ });
+ }
+ }
append_platform_devices(&mut command, &mut preserved_fds, &config)?;
debug!("Preserving FDs {:?}", preserved_fds);
diff --git a/virtualizationservice/aidl/android/system/virtualizationservice/InputDevice.aidl b/virtualizationservice/aidl/android/system/virtualizationservice/InputDevice.aidl
new file mode 100644
index 0000000..fe12291
--- /dev/null
+++ b/virtualizationservice/aidl/android/system/virtualizationservice/InputDevice.aidl
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.system.virtualizationservice;
+
+// Refer to https://crosvm.dev/book/devices/input.html
+union InputDevice {
+ // Add a single-touch touchscreen virtio-input device.
+ parcelable SingleTouch {
+ ParcelFileDescriptor pfd;
+ // Default values come from https://crosvm.dev/book/devices/input.html#single-touch
+ int width = 1280;
+ int height = 1080;
+ @utf8InCpp String name = "";
+ }
+ // Passes an event device node into the VM. The device will be grabbed (unusable from the host)
+ // and made available to the guest with the same configuration it shows on the host.
+ parcelable EvDev {
+ ParcelFileDescriptor pfd;
+ }
+
+ SingleTouch singleTouch;
+ EvDev evDev;
+}
diff --git a/virtualizationservice/aidl/android/system/virtualizationservice/VirtualMachineRawConfig.aidl b/virtualizationservice/aidl/android/system/virtualizationservice/VirtualMachineRawConfig.aidl
index 1a18bf8..86e26da 100644
--- a/virtualizationservice/aidl/android/system/virtualizationservice/VirtualMachineRawConfig.aidl
+++ b/virtualizationservice/aidl/android/system/virtualizationservice/VirtualMachineRawConfig.aidl
@@ -18,6 +18,7 @@
import android.system.virtualizationservice.CpuTopology;
import android.system.virtualizationservice.DiskImage;
import android.system.virtualizationservice.DisplayConfig;
+import android.system.virtualizationservice.InputDevice;
/** Raw configuration for running a VM. */
parcelable VirtualMachineRawConfig {
@@ -73,4 +74,7 @@
String[] devices;
@nullable DisplayConfig displayConfig;
+
+ /** List of input devices to the VM */
+ InputDevice[] inputDevices;
}