1*bb4ee6a4SAndroid Build Coastguard Worker // Copyright 2019 The ChromiumOS Authors 2*bb4ee6a4SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be 3*bb4ee6a4SAndroid Build Coastguard Worker // found in the LICENSE file. 4*bb4ee6a4SAndroid Build Coastguard Worker 5*bb4ee6a4SAndroid Build Coastguard Worker use std::collections::VecDeque; 6*bb4ee6a4SAndroid Build Coastguard Worker use std::fmt; 7*bb4ee6a4SAndroid Build Coastguard Worker use std::io; 8*bb4ee6a4SAndroid Build Coastguard Worker use std::io::Read; 9*bb4ee6a4SAndroid Build Coastguard Worker use std::io::Write; 10*bb4ee6a4SAndroid Build Coastguard Worker use std::iter::ExactSizeIterator; 11*bb4ee6a4SAndroid Build Coastguard Worker 12*bb4ee6a4SAndroid Build Coastguard Worker use base::AsRawDescriptor; 13*bb4ee6a4SAndroid Build Coastguard Worker use base::RawDescriptor; 14*bb4ee6a4SAndroid Build Coastguard Worker use base::ReadNotifier; 15*bb4ee6a4SAndroid Build Coastguard Worker use base::StreamChannel; 16*bb4ee6a4SAndroid Build Coastguard Worker use linux_input_sys::virtio_input_event; 17*bb4ee6a4SAndroid Build Coastguard Worker use linux_input_sys::InputEventDecoder; 18*bb4ee6a4SAndroid Build Coastguard Worker use serde::Deserialize; 19*bb4ee6a4SAndroid Build Coastguard Worker use serde::Serialize; 20*bb4ee6a4SAndroid Build Coastguard Worker use zerocopy::AsBytes; 21*bb4ee6a4SAndroid Build Coastguard Worker use zerocopy::FromZeroes; 22*bb4ee6a4SAndroid Build Coastguard Worker 23*bb4ee6a4SAndroid Build Coastguard Worker const EVENT_SIZE: usize = virtio_input_event::SIZE; 24*bb4ee6a4SAndroid Build Coastguard Worker const EVENT_BUFFER_LEN_MAX: usize = 64 * EVENT_SIZE; 25*bb4ee6a4SAndroid Build Coastguard Worker 26*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Copy, Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)] 27*bb4ee6a4SAndroid Build Coastguard Worker pub enum EventDeviceKind { 28*bb4ee6a4SAndroid Build Coastguard Worker /// Produces relative mouse motions, wheel, and button clicks while the real mouse is captured. 29*bb4ee6a4SAndroid Build Coastguard Worker Mouse, 30*bb4ee6a4SAndroid Build Coastguard Worker /// Produces absolute motion and touch events from the display window's events. 31*bb4ee6a4SAndroid Build Coastguard Worker Touchscreen, 32*bb4ee6a4SAndroid Build Coastguard Worker /// Produces key events while the display window has focus. 33*bb4ee6a4SAndroid Build Coastguard Worker Keyboard, 34*bb4ee6a4SAndroid Build Coastguard Worker } 35*bb4ee6a4SAndroid Build Coastguard Worker 36*bb4ee6a4SAndroid Build Coastguard Worker /// Encapsulates a virtual event device, such as a mouse or keyboard 37*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Deserialize, Serialize)] 38*bb4ee6a4SAndroid Build Coastguard Worker pub struct EventDevice { 39*bb4ee6a4SAndroid Build Coastguard Worker kind: EventDeviceKind, 40*bb4ee6a4SAndroid Build Coastguard Worker event_buffer: VecDeque<u8>, 41*bb4ee6a4SAndroid Build Coastguard Worker event_socket: StreamChannel, 42*bb4ee6a4SAndroid Build Coastguard Worker } 43*bb4ee6a4SAndroid Build Coastguard Worker 44*bb4ee6a4SAndroid Build Coastguard Worker impl EventDevice { new(kind: EventDeviceKind, mut event_socket: StreamChannel) -> EventDevice45*bb4ee6a4SAndroid Build Coastguard Worker pub fn new(kind: EventDeviceKind, mut event_socket: StreamChannel) -> EventDevice { 46*bb4ee6a4SAndroid Build Coastguard Worker let _ = event_socket.set_nonblocking(true); 47*bb4ee6a4SAndroid Build Coastguard Worker EventDevice { 48*bb4ee6a4SAndroid Build Coastguard Worker kind, 49*bb4ee6a4SAndroid Build Coastguard Worker event_buffer: Default::default(), 50*bb4ee6a4SAndroid Build Coastguard Worker event_socket, 51*bb4ee6a4SAndroid Build Coastguard Worker } 52*bb4ee6a4SAndroid Build Coastguard Worker } 53*bb4ee6a4SAndroid Build Coastguard Worker 54*bb4ee6a4SAndroid Build Coastguard Worker #[inline] mouse(event_socket: StreamChannel) -> EventDevice55*bb4ee6a4SAndroid Build Coastguard Worker pub fn mouse(event_socket: StreamChannel) -> EventDevice { 56*bb4ee6a4SAndroid Build Coastguard Worker Self::new(EventDeviceKind::Mouse, event_socket) 57*bb4ee6a4SAndroid Build Coastguard Worker } 58*bb4ee6a4SAndroid Build Coastguard Worker 59*bb4ee6a4SAndroid Build Coastguard Worker #[inline] touchscreen(event_socket: StreamChannel) -> EventDevice60*bb4ee6a4SAndroid Build Coastguard Worker pub fn touchscreen(event_socket: StreamChannel) -> EventDevice { 61*bb4ee6a4SAndroid Build Coastguard Worker Self::new(EventDeviceKind::Touchscreen, event_socket) 62*bb4ee6a4SAndroid Build Coastguard Worker } 63*bb4ee6a4SAndroid Build Coastguard Worker 64*bb4ee6a4SAndroid Build Coastguard Worker #[inline] keyboard(event_socket: StreamChannel) -> EventDevice65*bb4ee6a4SAndroid Build Coastguard Worker pub fn keyboard(event_socket: StreamChannel) -> EventDevice { 66*bb4ee6a4SAndroid Build Coastguard Worker Self::new(EventDeviceKind::Keyboard, event_socket) 67*bb4ee6a4SAndroid Build Coastguard Worker } 68*bb4ee6a4SAndroid Build Coastguard Worker 69*bb4ee6a4SAndroid Build Coastguard Worker #[inline] kind(&self) -> EventDeviceKind70*bb4ee6a4SAndroid Build Coastguard Worker pub fn kind(&self) -> EventDeviceKind { 71*bb4ee6a4SAndroid Build Coastguard Worker self.kind 72*bb4ee6a4SAndroid Build Coastguard Worker } 73*bb4ee6a4SAndroid Build Coastguard Worker 74*bb4ee6a4SAndroid Build Coastguard Worker /// Flushes the buffered events that did not fit into the underlying transport, if any. 75*bb4ee6a4SAndroid Build Coastguard Worker /// 76*bb4ee6a4SAndroid Build Coastguard Worker /// Returns `Ok(true)` if, after this function returns, there all the buffer of events is 77*bb4ee6a4SAndroid Build Coastguard Worker /// empty. flush_buffered_events(&mut self) -> io::Result<bool>78*bb4ee6a4SAndroid Build Coastguard Worker pub fn flush_buffered_events(&mut self) -> io::Result<bool> { 79*bb4ee6a4SAndroid Build Coastguard Worker while !self.event_buffer.is_empty() { 80*bb4ee6a4SAndroid Build Coastguard Worker let written = self.event_socket.write(self.event_buffer.as_slices().0)?; 81*bb4ee6a4SAndroid Build Coastguard Worker if written == 0 { 82*bb4ee6a4SAndroid Build Coastguard Worker return Ok(false); 83*bb4ee6a4SAndroid Build Coastguard Worker } 84*bb4ee6a4SAndroid Build Coastguard Worker self.event_buffer.drain(..written); 85*bb4ee6a4SAndroid Build Coastguard Worker } 86*bb4ee6a4SAndroid Build Coastguard Worker Ok(true) 87*bb4ee6a4SAndroid Build Coastguard Worker } 88*bb4ee6a4SAndroid Build Coastguard Worker is_buffered_events_empty(&self) -> bool89*bb4ee6a4SAndroid Build Coastguard Worker pub fn is_buffered_events_empty(&self) -> bool { 90*bb4ee6a4SAndroid Build Coastguard Worker self.event_buffer.is_empty() 91*bb4ee6a4SAndroid Build Coastguard Worker } 92*bb4ee6a4SAndroid Build Coastguard Worker 93*bb4ee6a4SAndroid Build Coastguard Worker /// Determines if there is space in the event buffer for the given number 94*bb4ee6a4SAndroid Build Coastguard Worker /// of events. The buffer is capped at `EVENT_BUFFER_LEN_MAX`. 95*bb4ee6a4SAndroid Build Coastguard Worker #[inline] can_buffer_events(&self, num_events: usize) -> bool96*bb4ee6a4SAndroid Build Coastguard Worker fn can_buffer_events(&self, num_events: usize) -> bool { 97*bb4ee6a4SAndroid Build Coastguard Worker let event_bytes = match EVENT_SIZE.checked_mul(num_events) { 98*bb4ee6a4SAndroid Build Coastguard Worker Some(bytes) => bytes, 99*bb4ee6a4SAndroid Build Coastguard Worker None => return false, 100*bb4ee6a4SAndroid Build Coastguard Worker }; 101*bb4ee6a4SAndroid Build Coastguard Worker let free_bytes = EVENT_BUFFER_LEN_MAX.saturating_sub(self.event_buffer.len()); 102*bb4ee6a4SAndroid Build Coastguard Worker 103*bb4ee6a4SAndroid Build Coastguard Worker free_bytes >= event_bytes 104*bb4ee6a4SAndroid Build Coastguard Worker } 105*bb4ee6a4SAndroid Build Coastguard Worker send_report<E: IntoIterator<Item = virtio_input_event>>( &mut self, events: E, ) -> io::Result<bool> where E::IntoIter: ExactSizeIterator,106*bb4ee6a4SAndroid Build Coastguard Worker pub fn send_report<E: IntoIterator<Item = virtio_input_event>>( 107*bb4ee6a4SAndroid Build Coastguard Worker &mut self, 108*bb4ee6a4SAndroid Build Coastguard Worker events: E, 109*bb4ee6a4SAndroid Build Coastguard Worker ) -> io::Result<bool> 110*bb4ee6a4SAndroid Build Coastguard Worker where 111*bb4ee6a4SAndroid Build Coastguard Worker E::IntoIter: ExactSizeIterator, 112*bb4ee6a4SAndroid Build Coastguard Worker { 113*bb4ee6a4SAndroid Build Coastguard Worker let it = events.into_iter(); 114*bb4ee6a4SAndroid Build Coastguard Worker 115*bb4ee6a4SAndroid Build Coastguard Worker if !self.can_buffer_events(it.len() + 1) { 116*bb4ee6a4SAndroid Build Coastguard Worker return Ok(false); 117*bb4ee6a4SAndroid Build Coastguard Worker } 118*bb4ee6a4SAndroid Build Coastguard Worker 119*bb4ee6a4SAndroid Build Coastguard Worker for event in it { 120*bb4ee6a4SAndroid Build Coastguard Worker let bytes = event.as_bytes(); 121*bb4ee6a4SAndroid Build Coastguard Worker self.event_buffer.extend(bytes.iter()); 122*bb4ee6a4SAndroid Build Coastguard Worker } 123*bb4ee6a4SAndroid Build Coastguard Worker 124*bb4ee6a4SAndroid Build Coastguard Worker self.event_buffer 125*bb4ee6a4SAndroid Build Coastguard Worker .extend(virtio_input_event::syn().as_bytes().iter()); 126*bb4ee6a4SAndroid Build Coastguard Worker 127*bb4ee6a4SAndroid Build Coastguard Worker self.flush_buffered_events() 128*bb4ee6a4SAndroid Build Coastguard Worker } 129*bb4ee6a4SAndroid Build Coastguard Worker 130*bb4ee6a4SAndroid Build Coastguard Worker /// Sends the given `event`, returning `Ok(true)` if, after this function returns, there are no 131*bb4ee6a4SAndroid Build Coastguard Worker /// buffered events remaining. send_event_encoded(&mut self, event: virtio_input_event) -> io::Result<bool>132*bb4ee6a4SAndroid Build Coastguard Worker pub fn send_event_encoded(&mut self, event: virtio_input_event) -> io::Result<bool> { 133*bb4ee6a4SAndroid Build Coastguard Worker if !self.flush_buffered_events()? { 134*bb4ee6a4SAndroid Build Coastguard Worker return Ok(false); 135*bb4ee6a4SAndroid Build Coastguard Worker } 136*bb4ee6a4SAndroid Build Coastguard Worker 137*bb4ee6a4SAndroid Build Coastguard Worker let bytes = event.as_bytes(); 138*bb4ee6a4SAndroid Build Coastguard Worker let written = self.event_socket.write(bytes)?; 139*bb4ee6a4SAndroid Build Coastguard Worker 140*bb4ee6a4SAndroid Build Coastguard Worker if written == bytes.len() { 141*bb4ee6a4SAndroid Build Coastguard Worker return Ok(true); 142*bb4ee6a4SAndroid Build Coastguard Worker } 143*bb4ee6a4SAndroid Build Coastguard Worker 144*bb4ee6a4SAndroid Build Coastguard Worker if self.can_buffer_events(1) { 145*bb4ee6a4SAndroid Build Coastguard Worker self.event_buffer.extend(bytes[written..].iter()); 146*bb4ee6a4SAndroid Build Coastguard Worker } 147*bb4ee6a4SAndroid Build Coastguard Worker 148*bb4ee6a4SAndroid Build Coastguard Worker Ok(false) 149*bb4ee6a4SAndroid Build Coastguard Worker } 150*bb4ee6a4SAndroid Build Coastguard Worker recv_event_encoded(&self) -> io::Result<virtio_input_event>151*bb4ee6a4SAndroid Build Coastguard Worker pub fn recv_event_encoded(&self) -> io::Result<virtio_input_event> { 152*bb4ee6a4SAndroid Build Coastguard Worker let mut event = virtio_input_event::new_zeroed(); 153*bb4ee6a4SAndroid Build Coastguard Worker (&self.event_socket).read_exact(event.as_bytes_mut())?; 154*bb4ee6a4SAndroid Build Coastguard Worker Ok(event) 155*bb4ee6a4SAndroid Build Coastguard Worker } 156*bb4ee6a4SAndroid Build Coastguard Worker } 157*bb4ee6a4SAndroid Build Coastguard Worker 158*bb4ee6a4SAndroid Build Coastguard Worker impl AsRawDescriptor for EventDevice { as_raw_descriptor(&self) -> RawDescriptor159*bb4ee6a4SAndroid Build Coastguard Worker fn as_raw_descriptor(&self) -> RawDescriptor { 160*bb4ee6a4SAndroid Build Coastguard Worker self.event_socket.as_raw_descriptor() 161*bb4ee6a4SAndroid Build Coastguard Worker } 162*bb4ee6a4SAndroid Build Coastguard Worker } 163*bb4ee6a4SAndroid Build Coastguard Worker 164*bb4ee6a4SAndroid Build Coastguard Worker impl ReadNotifier for EventDevice { get_read_notifier(&self) -> &dyn AsRawDescriptor165*bb4ee6a4SAndroid Build Coastguard Worker fn get_read_notifier(&self) -> &dyn AsRawDescriptor { 166*bb4ee6a4SAndroid Build Coastguard Worker self.event_socket.get_read_notifier() 167*bb4ee6a4SAndroid Build Coastguard Worker } 168*bb4ee6a4SAndroid Build Coastguard Worker } 169*bb4ee6a4SAndroid Build Coastguard Worker 170*bb4ee6a4SAndroid Build Coastguard Worker impl fmt::Debug for EventDevice { fmt(&self, f: &mut fmt::Formatter) -> fmt::Result171*bb4ee6a4SAndroid Build Coastguard Worker fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 172*bb4ee6a4SAndroid Build Coastguard Worker write!(f, "Event device ({:?})", self.kind) 173*bb4ee6a4SAndroid Build Coastguard Worker } 174*bb4ee6a4SAndroid Build Coastguard Worker } 175