xref: /aosp_15_r20/external/crosvm/devices/src/virtio/input/event_source.rs (revision bb4ee6a4ae7042d18b07a98463b9c8b875e44b39)
1 // Copyright 2019 The ChromiumOS Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 use std::collections::VecDeque;
6 use std::io::Read;
7 use std::io::Write;
8 
9 use base::warn;
10 use base::AsRawDescriptor;
11 use base::RawDescriptor;
12 use linux_input_sys::constants::*;
13 use linux_input_sys::input_event;
14 use linux_input_sys::virtio_input_event;
15 use linux_input_sys::InputEventDecoder;
16 use zerocopy::AsBytes;
17 
18 use super::evdev::grab_evdev;
19 use super::evdev::ungrab_evdev;
20 use super::InputError;
21 use super::Result;
22 
23 /// Encapsulates a socket or device node into an abstract event source, providing a common
24 /// interface.
25 /// It supports read and write operations to provide and accept events just like an event device
26 /// node would, except that it handles virtio_input_event instead of input_event structures.
27 /// It's necessary to call receive_events() before events are available for read.
28 pub trait EventSource: AsRawDescriptor {
29     /// Perform any necessary initialization before receiving and sending events from/to the source.
init(&mut self) -> Result<()>30     fn init(&mut self) -> Result<()> {
31         Ok(())
32     }
33     /// Perform any necessary cleanup when the device will no longer be used.
finalize(&mut self) -> Result<()>34     fn finalize(&mut self) -> Result<()> {
35         Ok(())
36     }
37 
38     /// Receive events from the source, filters them and stores them in a queue for future
39     /// consumption by reading from this object. Returns the number of new non filtered events
40     /// received. This function may block waiting for events to be available.
receive_events(&mut self) -> Result<usize>41     fn receive_events(&mut self) -> Result<usize>;
42     /// Returns the number of received events that have not been filtered or consumed yet.
available_events_count(&self) -> usize43     fn available_events_count(&self) -> usize;
44     /// Returns the next available event
pop_available_event(&mut self) -> Option<virtio_input_event>45     fn pop_available_event(&mut self) -> Option<virtio_input_event>;
46     /// Sends a status update event to the source
send_event(&mut self, vio_evt: &virtio_input_event) -> Result<()>47     fn send_event(&mut self, vio_evt: &virtio_input_event) -> Result<()>;
48 }
49 
50 /// Encapsulates implementation details common to all kinds of event sources.
51 pub struct EventSourceImpl<T> {
52     source: T,
53     queue: VecDeque<virtio_input_event>,
54     read_buffer: Vec<u8>,
55     read_idx: usize,
56 }
57 
58 impl<T: AsRawDescriptor> EventSourceImpl<T> {
as_raw_descriptor(&self) -> RawDescriptor59     fn as_raw_descriptor(&self) -> RawDescriptor {
60         self.source.as_raw_descriptor()
61     }
62 }
63 
64 impl<T> EventSourceImpl<T>
65 where
66     T: Read + Write,
67 {
68     // Receive events from the source and store them in a queue.
receive_events<E: InputEventDecoder>(&mut self) -> Result<usize>69     fn receive_events<E: InputEventDecoder>(&mut self) -> Result<usize> {
70         let read = self
71             .source
72             .read(&mut self.read_buffer[self.read_idx..])
73             .map_err(InputError::EventsReadError)?;
74         let buff_size = read + self.read_idx;
75 
76         for evt_slice in self.read_buffer[..buff_size].chunks_exact(E::SIZE) {
77             self.queue.push_back(E::decode(evt_slice));
78         }
79 
80         let remainder = buff_size % E::SIZE;
81         // If there is an incomplete event at the end of the buffer, it needs to be moved to the
82         // beginning and the next read operation must write right after it.
83         if remainder != 0 {
84             warn!("read incomplete event from source");
85             // The copy should only happen if there is at least one complete event in the buffer,
86             // otherwise source and destination would be the same.
87             if buff_size != remainder {
88                 let (des, src) = self.read_buffer.split_at_mut(buff_size - remainder);
89                 des[..remainder].copy_from_slice(&src[..remainder]);
90             }
91         }
92         self.read_idx = remainder;
93 
94         let received_events = buff_size / E::SIZE;
95 
96         Ok(received_events)
97     }
98 
available_events(&self) -> usize99     fn available_events(&self) -> usize {
100         self.queue.len()
101     }
102 
pop_available_event(&mut self) -> Option<virtio_input_event>103     fn pop_available_event(&mut self) -> Option<virtio_input_event> {
104         self.queue.pop_front()
105     }
106 
send_event(&mut self, vio_evt: &virtio_input_event, encoding: EventType) -> Result<()>107     fn send_event(&mut self, vio_evt: &virtio_input_event, encoding: EventType) -> Result<()> {
108         // Miscellaneous events produced by the device are sent back to it by the kernel input
109         // subsystem, but because these events are handled by the host kernel as well as the
110         // guest the device would get them twice. Which would prompt the device to send the
111         // event to the guest again entering an infinite loop.
112         if vio_evt.type_ != EV_MSC {
113             let evt;
114             let event_bytes = match encoding {
115                 EventType::InputEvent => {
116                     evt = input_event::from_virtio_input_event(vio_evt);
117                     evt.as_bytes()
118                 }
119                 EventType::VirtioInputEvent => vio_evt.as_bytes(),
120             };
121             self.source
122                 .write_all(event_bytes)
123                 .map_err(InputError::EventsWriteError)?;
124         }
125         Ok(())
126     }
127 
new(source: T, capacity: usize) -> EventSourceImpl<T>128     fn new(source: T, capacity: usize) -> EventSourceImpl<T> {
129         EventSourceImpl {
130             source,
131             queue: VecDeque::new(),
132             read_buffer: vec![0; capacity],
133             read_idx: 0,
134         }
135     }
136 }
137 
138 enum EventType {
139     VirtioInputEvent,
140     InputEvent,
141 }
142 
143 /// Encapsulates a (unix) socket as an event source.
144 pub struct SocketEventSource<T> {
145     evt_source_impl: EventSourceImpl<T>,
146 }
147 
148 impl<T> SocketEventSource<T>
149 where
150     T: Read + Write + AsRawDescriptor,
151 {
new(source: T) -> SocketEventSource<T>152     pub fn new(source: T) -> SocketEventSource<T> {
153         SocketEventSource {
154             evt_source_impl: EventSourceImpl::new(source, 16 * virtio_input_event::SIZE),
155         }
156     }
157 }
158 
159 impl<T: AsRawDescriptor> AsRawDescriptor for SocketEventSource<T> {
as_raw_descriptor(&self) -> RawDescriptor160     fn as_raw_descriptor(&self) -> RawDescriptor {
161         self.evt_source_impl.as_raw_descriptor()
162     }
163 }
164 
165 impl<T> EventSource for SocketEventSource<T>
166 where
167     T: Read + Write + AsRawDescriptor,
168 {
init(&mut self) -> Result<()>169     fn init(&mut self) -> Result<()> {
170         Ok(())
171     }
172 
finalize(&mut self) -> Result<()>173     fn finalize(&mut self) -> Result<()> {
174         Ok(())
175     }
176 
receive_events(&mut self) -> Result<usize>177     fn receive_events(&mut self) -> Result<usize> {
178         self.evt_source_impl.receive_events::<virtio_input_event>()
179     }
180 
available_events_count(&self) -> usize181     fn available_events_count(&self) -> usize {
182         self.evt_source_impl.available_events()
183     }
184 
pop_available_event(&mut self) -> Option<virtio_input_event>185     fn pop_available_event(&mut self) -> Option<virtio_input_event> {
186         self.evt_source_impl.pop_available_event()
187     }
188 
send_event(&mut self, vio_evt: &virtio_input_event) -> Result<()>189     fn send_event(&mut self, vio_evt: &virtio_input_event) -> Result<()> {
190         self.evt_source_impl
191             .send_event(vio_evt, EventType::VirtioInputEvent)
192     }
193 }
194 
195 /// Encapsulates an event device node as an event source
196 pub struct EvdevEventSource<T> {
197     evt_source_impl: EventSourceImpl<T>,
198 }
199 
200 impl<T> EvdevEventSource<T>
201 where
202     T: Read + Write + AsRawDescriptor,
203 {
new(source: T) -> EvdevEventSource<T>204     pub fn new(source: T) -> EvdevEventSource<T> {
205         EvdevEventSource {
206             evt_source_impl: EventSourceImpl::new(source, 16 * input_event::SIZE),
207         }
208     }
209 }
210 
211 impl<T: AsRawDescriptor> AsRawDescriptor for EvdevEventSource<T> {
as_raw_descriptor(&self) -> RawDescriptor212     fn as_raw_descriptor(&self) -> RawDescriptor {
213         self.evt_source_impl.as_raw_descriptor()
214     }
215 }
216 
217 impl<T> EventSource for EvdevEventSource<T>
218 where
219     T: Read + Write + AsRawDescriptor,
220 {
init(&mut self) -> Result<()>221     fn init(&mut self) -> Result<()> {
222         grab_evdev(self)
223     }
224 
finalize(&mut self) -> Result<()>225     fn finalize(&mut self) -> Result<()> {
226         ungrab_evdev(self)
227     }
228 
receive_events(&mut self) -> Result<usize>229     fn receive_events(&mut self) -> Result<usize> {
230         self.evt_source_impl.receive_events::<input_event>()
231     }
232 
available_events_count(&self) -> usize233     fn available_events_count(&self) -> usize {
234         self.evt_source_impl.available_events()
235     }
236 
pop_available_event(&mut self) -> Option<virtio_input_event>237     fn pop_available_event(&mut self) -> Option<virtio_input_event> {
238         self.evt_source_impl.pop_available_event()
239     }
240 
send_event(&mut self, vio_evt: &virtio_input_event) -> Result<()>241     fn send_event(&mut self, vio_evt: &virtio_input_event) -> Result<()> {
242         self.evt_source_impl
243             .send_event(vio_evt, EventType::InputEvent)
244     }
245 }
246 
247 #[cfg(test)]
248 mod tests {
249     use std::cmp::min;
250     use std::io::Read;
251     use std::io::Write;
252 
253     use data_model::Le16;
254     use data_model::SLe32;
255     use linux_input_sys::InputEventDecoder;
256     use zerocopy::AsBytes;
257 
258     use crate::virtio::input::event_source::input_event;
259     use crate::virtio::input::event_source::virtio_input_event;
260     use crate::virtio::input::event_source::EventSourceImpl;
261 
262     struct SourceMock {
263         events: Vec<u8>,
264     }
265 
266     impl SourceMock {
new(evts: &[input_event]) -> SourceMock267         fn new(evts: &[input_event]) -> SourceMock {
268             let mut events: Vec<u8> = vec![];
269             for evt in evts {
270                 for byte in evt.as_bytes() {
271                     events.push(*byte);
272                 }
273             }
274             SourceMock { events }
275         }
276     }
277 
278     impl Read for SourceMock {
read(&mut self, buf: &mut [u8]) -> std::result::Result<usize, std::io::Error>279         fn read(&mut self, buf: &mut [u8]) -> std::result::Result<usize, std::io::Error> {
280             let copy_size = min(buf.len(), self.events.len());
281             buf[..copy_size].copy_from_slice(&self.events[..copy_size]);
282             Ok(copy_size)
283         }
284     }
285     impl Write for SourceMock {
write(&mut self, buf: &[u8]) -> std::result::Result<usize, std::io::Error>286         fn write(&mut self, buf: &[u8]) -> std::result::Result<usize, std::io::Error> {
287             Ok(buf.len())
288         }
289 
flush(&mut self) -> std::result::Result<(), std::io::Error>290         fn flush(&mut self) -> std::result::Result<(), std::io::Error> {
291             Ok(())
292         }
293     }
294 
295     #[test]
empty_new()296     fn empty_new() {
297         let mut source = EventSourceImpl::new(SourceMock::new(&[]), 128);
298         assert_eq!(
299             source.available_events(),
300             0,
301             "zero events should be available"
302         );
303         assert_eq!(
304             source.pop_available_event().is_none(),
305             true,
306             "no events should be available"
307         );
308     }
309 
310     #[test]
empty_receive()311     fn empty_receive() {
312         let mut source = EventSourceImpl::new(SourceMock::new(&[]), 128);
313         assert_eq!(
314             source.receive_events::<input_event>().unwrap(),
315             0,
316             "zero events should be received"
317         );
318         assert_eq!(
319             source.pop_available_event().is_none(),
320             true,
321             "no events should be available"
322         );
323     }
324 
instantiate_input_events(count: usize) -> Vec<input_event>325     fn instantiate_input_events(count: usize) -> Vec<input_event> {
326         let mut ret: Vec<input_event> = Vec::with_capacity(count);
327         for idx in 0..count {
328             ret.push(input_event {
329                 timestamp_fields: [0, 0],
330                 type_: 3 * (idx as u16) + 1,
331                 code: 3 * (idx as u16) + 2,
332                 value: if idx % 2 == 0 {
333                     3 * (idx as i32) + 3
334                 } else {
335                     -3 * (idx as i32) - 3
336                 },
337             });
338         }
339         ret
340     }
341 
assert_events_match(e1: &virtio_input_event, e2: &input_event)342     fn assert_events_match(e1: &virtio_input_event, e2: &input_event) {
343         assert_eq!(e1.type_, Le16::from(e2.type_), "type should match");
344         assert_eq!(e1.code, Le16::from(e2.code), "code should match");
345         assert_eq!(e1.value, SLe32::from(e2.value), "value should match");
346     }
347 
348     #[test]
partial_pop()349     fn partial_pop() {
350         let evts = instantiate_input_events(4usize);
351         let mut source = EventSourceImpl::new(SourceMock::new(&evts), input_event::SIZE * 4);
352         assert_eq!(
353             source.receive_events::<input_event>().unwrap(),
354             evts.len(),
355             "should receive all events"
356         );
357         let evt_opt = source.pop_available_event();
358         assert_eq!(evt_opt.is_some(), true, "event should have been poped");
359         let evt = evt_opt.unwrap();
360         assert_events_match(&evt, &evts[0]);
361     }
362 
363     #[test]
total_pop()364     fn total_pop() {
365         const EVENT_COUNT: usize = 4;
366         let evts = instantiate_input_events(EVENT_COUNT);
367         let mut source = EventSourceImpl::new(SourceMock::new(&evts), input_event::SIZE * 4);
368         assert_eq!(
369             source.receive_events::<input_event>().unwrap(),
370             evts.len(),
371             "should receive all events"
372         );
373         for expected_evt in evts[..EVENT_COUNT].iter() {
374             let evt = source.pop_available_event().unwrap();
375             assert_events_match(&evt, expected_evt);
376         }
377         assert_eq!(
378             source.available_events(),
379             0,
380             "there should be no events left"
381         );
382         assert_eq!(
383             source.pop_available_event().is_none(),
384             true,
385             "no events should pop"
386         );
387     }
388 }
389