diff options
author | Zach Reizner <zachr@google.com> | 2019-11-22 17:34:58 -0800 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2019-12-11 00:25:55 +0000 |
commit | 65b98f1ccc2ce1d52c12f75a224a259fd399e555 (patch) | |
tree | 0e73ceacdb9385cb44521a94303230aec3d8f36a /src | |
parent | 2767223fdbcf189ccebbffbec8b3a0f254d9d40e (diff) | |
download | crosvm-65b98f1ccc2ce1d52c12f75a224a259fd399e555.tar crosvm-65b98f1ccc2ce1d52c12f75a224a259fd399e555.tar.gz crosvm-65b98f1ccc2ce1d52c12f75a224a259fd399e555.tar.bz2 crosvm-65b98f1ccc2ce1d52c12f75a224a259fd399e555.tar.lz crosvm-65b98f1ccc2ce1d52c12f75a224a259fd399e555.tar.xz crosvm-65b98f1ccc2ce1d52c12f75a224a259fd399e555.tar.zst crosvm-65b98f1ccc2ce1d52c12f75a224a259fd399e555.zip |
utilize EventDevices to make virtio-input devices
BUG=chromium:1023975 TEST=./build_test Change-Id: I10267e535d4d1dae90b2b5f30db046c388791a16 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/1930409 Reviewed-by: Zach Reizner <zachr@chromium.org> Commit-Queue: Zach Reizner <zachr@chromium.org> Tested-by: Zach Reizner <zachr@chromium.org> Tested-by: kokoro <noreply+kokoro@google.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/crosvm.rs | 4 | ||||
-rw-r--r-- | src/linux.rs | 71 | ||||
-rw-r--r-- | src/main.rs | 8 |
3 files changed, 71 insertions, 12 deletions
diff --git a/src/crosvm.rs b/src/crosvm.rs index 0e0e218..8a15c6b 100644 --- a/src/crosvm.rs +++ b/src/crosvm.rs @@ -155,6 +155,8 @@ pub struct Config { pub cras_audio: bool, pub cras_capture: bool, pub null_audio: bool, + pub display_window_keyboard: bool, + pub display_window_mouse: bool, pub serial_parameters: BTreeMap<u8, SerialParameters>, pub syslog_tag: Option<String>, pub virtio_single_touch: Option<TouchDeviceOption>, @@ -194,6 +196,8 @@ impl Default for Config { wayland_socket_path: None, wayland_dmabuf: false, x_display: None, + display_window_keyboard: false, + display_window_mouse: false, shared_dirs: Vec::new(), sandbox: !cfg!(feature = "default-no-sandbox"), seccomp_policy_dir: PathBuf::from(SECCOMP_POLICY_DIR), diff --git a/src/linux.rs b/src/linux.rs index a9a3445..57b3ef5 100644 --- a/src/linux.rs +++ b/src/linux.rs @@ -28,6 +28,8 @@ use std::time::{Duration, SystemTime, UNIX_EPOCH}; use libc::{self, c_int, gid_t, uid_t}; use audio_streams::DummyStreamSource; +#[cfg(feature = "gpu")] +use devices::virtio::EventDevice; use devices::virtio::{self, VirtioDevice}; use devices::{ self, HostBackendDeviceProvider, PciDevice, VfioDevice, VfioPciDevice, VirtioPciDevice, @@ -456,7 +458,7 @@ fn create_tpm_device(cfg: &Config) -> DeviceResult { } fn create_single_touch_device(cfg: &Config, single_touch_spec: &TouchDeviceOption) -> DeviceResult { - let socket = create_input_socket(&single_touch_spec.path).map_err(|e| { + let socket = single_touch_spec.path.into_unix_stream().map_err(|e| { error!("failed configuring virtio single touch: {:?}", e); e })?; @@ -470,7 +472,7 @@ fn create_single_touch_device(cfg: &Config, single_touch_spec: &TouchDeviceOptio } fn create_trackpad_device(cfg: &Config, trackpad_spec: &TouchDeviceOption) -> DeviceResult { - let socket = create_input_socket(&trackpad_spec.path).map_err(|e| { + let socket = trackpad_spec.path.into_unix_stream().map_err(|e| { error!("failed configuring virtio trackpad: {}", e); e })?; @@ -484,8 +486,8 @@ fn create_trackpad_device(cfg: &Config, trackpad_spec: &TouchDeviceOption) -> De }) } -fn create_mouse_device(cfg: &Config, mouse_socket: &Path) -> DeviceResult { - let socket = create_input_socket(&mouse_socket).map_err(|e| { +fn create_mouse_device<T: IntoUnixStream>(cfg: &Config, mouse_socket: T) -> DeviceResult { + let socket = mouse_socket.into_unix_stream().map_err(|e| { error!("failed configuring virtio mouse: {}", e); e })?; @@ -498,8 +500,8 @@ fn create_mouse_device(cfg: &Config, mouse_socket: &Path) -> DeviceResult { }) } -fn create_keyboard_device(cfg: &Config, keyboard_socket: &Path) -> DeviceResult { - let socket = create_input_socket(&keyboard_socket).map_err(|e| { +fn create_keyboard_device<T: IntoUnixStream>(cfg: &Config, keyboard_socket: T) -> DeviceResult { + let socket = keyboard_socket.into_unix_stream().map_err(|e| { error!("failed configuring virtio keyboard: {}", e); e })?; @@ -589,6 +591,7 @@ fn create_gpu_device( gpu_sockets: Vec<virtio::resource_bridge::ResourceResponseSocket>, wayland_socket_path: Option<PathBuf>, x_display: Option<String>, + event_devices: Vec<EventDevice>, ) -> DeviceResult { let jailed_wayland_path = Path::new("/wayland-0"); @@ -615,6 +618,7 @@ fn create_gpu_device( gpu_sockets, display_backends, cfg.gpu_parameters.as_ref().unwrap(), + event_devices, ); let jail = match simple_jail(&cfg, "gpu_device.policy")? { @@ -986,6 +990,31 @@ fn create_virtio_devices( #[cfg(feature = "gpu")] { if cfg.gpu_parameters.is_some() { + let mut event_devices = Vec::new(); + if cfg.display_window_mouse { + let (event_device_socket, virtio_dev_socket) = + UnixStream::pair().map_err(Error::CreateSocket)?; + // TODO(nkgold): the width/height here should match the display's height/width. When + // those settings are available as CLI options, we should use the CLI options here + // as well. + let dev = virtio::new_single_touch(virtio_dev_socket, 1280, 1024) + .map_err(Error::InputDeviceNew)?; + devs.push(VirtioDeviceStub { + dev: Box::new(dev), + jail: simple_jail(&cfg, "input_device.policy")?, + }); + event_devices.push(EventDevice::touchscreen(event_device_socket)); + } + if cfg.display_window_keyboard { + let (event_device_socket, virtio_dev_socket) = + UnixStream::pair().map_err(Error::CreateSocket)?; + let dev = virtio::new_keyboard(virtio_dev_socket).map_err(Error::InputDeviceNew)?; + devs.push(VirtioDeviceStub { + dev: Box::new(dev), + jail: simple_jail(&cfg, "input_device.policy")?, + }); + event_devices.push(EventDevice::keyboard(event_device_socket)); + } devs.push(create_gpu_device( cfg, _exit_evt, @@ -993,6 +1022,7 @@ fn create_virtio_devices( resource_bridges, cfg.wayland_socket_path.clone(), cfg.x_display.clone(), + event_devices, )?); } } @@ -1160,12 +1190,29 @@ fn raw_fd_from_path(path: &Path) -> Result<RawFd> { validate_raw_fd(raw_fd).map_err(Error::ValidateRawFd) } -fn create_input_socket(path: &Path) -> Result<UnixStream> { - if path.parent() == Some(Path::new("/proc/self/fd")) { - // Safe because we will validate |raw_fd|. - unsafe { Ok(UnixStream::from_raw_fd(raw_fd_from_path(path)?)) } - } else { - UnixStream::connect(path).map_err(Error::InputEventsOpen) +trait IntoUnixStream { + fn into_unix_stream(self) -> Result<UnixStream>; +} + +impl<'a> IntoUnixStream for &'a Path { + fn into_unix_stream(self) -> Result<UnixStream> { + if self.parent() == Some(Path::new("/proc/self/fd")) { + // Safe because we will validate |raw_fd|. + unsafe { Ok(UnixStream::from_raw_fd(raw_fd_from_path(self)?)) } + } else { + UnixStream::connect(self).map_err(Error::InputEventsOpen) + } + } +} +impl<'a> IntoUnixStream for &'a PathBuf { + fn into_unix_stream(self) -> Result<UnixStream> { + self.as_path().into_unix_stream() + } +} + +impl IntoUnixStream for UnixStream { + fn into_unix_stream(self) -> Result<UnixStream> { + Ok(self) } } diff --git a/src/main.rs b/src/main.rs index 9c97c4d..7f12841 100644 --- a/src/main.rs +++ b/src/main.rs @@ -511,6 +511,12 @@ fn set_argument(cfg: &mut Config, name: &str, value: Option<&str>) -> argument:: } cfg.x_display = Some(value.unwrap().to_owned()); } + "display-window-keyboard" => { + cfg.display_window_keyboard = true; + } + "display-window-mouse" => { + cfg.display_window_mouse = true; + } "socket" => { if cfg.socket_path.is_some() { return Err(argument::Error::TooManyArguments( @@ -931,6 +937,8 @@ fn run_vm(args: std::env::Args) -> std::result::Result<(), ()> { "), Argument::value("syslog-tag", "TAG", "When logging to syslog, use the provided tag."), Argument::value("x-display", "DISPLAY", "X11 display name to use."), + Argument::flag("display-window-keyboard", "Capture keyboard input from the display window."), + Argument::flag("display-window-mouse", "Capture keyboard input from the display window."), Argument::value("wayland-sock", "PATH", "Path to the Wayland socket to use."), #[cfg(feature = "wl-dmabuf")] Argument::flag("wayland-dmabuf", "Enable support for DMABufs in Wayland device."), |