devices/virtio/input/
event_source.rs

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
5use std::collections::VecDeque;
6use std::io::Read;
7use std::io::Write;
8
9use base::warn;
10use base::AsRawDescriptor;
11use base::RawDescriptor;
12use linux_input_sys::constants::*;
13use linux_input_sys::input_event;
14use linux_input_sys::virtio_input_event;
15use linux_input_sys::InputEventDecoder;
16use zerocopy::IntoBytes;
17
18use super::evdev::grab_evdev;
19use super::evdev::ungrab_evdev;
20use super::InputError;
21use 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.
28pub trait EventSource: AsRawDescriptor {
29    /// Perform any necessary initialization before receiving and sending events from/to the source.
30    fn init(&mut self) -> Result<()> {
31        Ok(())
32    }
33    /// Perform any necessary cleanup when the device will no longer be used.
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.
41    fn receive_events(&mut self) -> Result<usize>;
42    /// Returns the number of received events that have not been filtered or consumed yet.
43    fn available_events_count(&self) -> usize;
44    /// Returns the next available event
45    fn pop_available_event(&mut self) -> Option<virtio_input_event>;
46    /// Sends a status update event to the source
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.
51pub struct EventSourceImpl<T> {
52    source: T,
53    queue: VecDeque<virtio_input_event>,
54    read_buffer: Vec<u8>,
55    read_idx: usize,
56}
57
58impl<T: AsRawDescriptor> EventSourceImpl<T> {
59    fn as_raw_descriptor(&self) -> RawDescriptor {
60        self.source.as_raw_descriptor()
61    }
62}
63
64impl<T> EventSourceImpl<T>
65where
66    T: Read + Write,
67{
68    // Receive events from the source and store them in a queue.
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
99    fn available_events(&self) -> usize {
100        self.queue.len()
101    }
102
103    fn pop_available_event(&mut self) -> Option<virtio_input_event> {
104        self.queue.pop_front()
105    }
106
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
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
138enum EventType {
139    VirtioInputEvent,
140    InputEvent,
141}
142
143/// Encapsulates a (unix) socket as an event source.
144pub struct SocketEventSource<T> {
145    evt_source_impl: EventSourceImpl<T>,
146}
147
148impl<T> SocketEventSource<T>
149where
150    T: Read + Write + AsRawDescriptor,
151{
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
159impl<T: AsRawDescriptor> AsRawDescriptor for SocketEventSource<T> {
160    fn as_raw_descriptor(&self) -> RawDescriptor {
161        self.evt_source_impl.as_raw_descriptor()
162    }
163}
164
165impl<T> EventSource for SocketEventSource<T>
166where
167    T: Read + Write + AsRawDescriptor,
168{
169    fn init(&mut self) -> Result<()> {
170        Ok(())
171    }
172
173    fn finalize(&mut self) -> Result<()> {
174        Ok(())
175    }
176
177    fn receive_events(&mut self) -> Result<usize> {
178        self.evt_source_impl.receive_events::<virtio_input_event>()
179    }
180
181    fn available_events_count(&self) -> usize {
182        self.evt_source_impl.available_events()
183    }
184
185    fn pop_available_event(&mut self) -> Option<virtio_input_event> {
186        self.evt_source_impl.pop_available_event()
187    }
188
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
196pub struct EvdevEventSource<T> {
197    evt_source_impl: EventSourceImpl<T>,
198}
199
200impl<T> EvdevEventSource<T>
201where
202    T: Read + Write + AsRawDescriptor,
203{
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
211impl<T: AsRawDescriptor> AsRawDescriptor for EvdevEventSource<T> {
212    fn as_raw_descriptor(&self) -> RawDescriptor {
213        self.evt_source_impl.as_raw_descriptor()
214    }
215}
216
217impl<T> EventSource for EvdevEventSource<T>
218where
219    T: Read + Write + AsRawDescriptor,
220{
221    fn init(&mut self) -> Result<()> {
222        grab_evdev(self)
223    }
224
225    fn finalize(&mut self) -> Result<()> {
226        ungrab_evdev(self)
227    }
228
229    fn receive_events(&mut self) -> Result<usize> {
230        self.evt_source_impl.receive_events::<input_event>()
231    }
232
233    fn available_events_count(&self) -> usize {
234        self.evt_source_impl.available_events()
235    }
236
237    fn pop_available_event(&mut self) -> Option<virtio_input_event> {
238        self.evt_source_impl.pop_available_event()
239    }
240
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)]
248mod 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::IntoBytes;
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 {
267        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 {
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 {
286        fn write(&mut self, buf: &[u8]) -> std::result::Result<usize, std::io::Error> {
287            Ok(buf.len())
288        }
289
290        fn flush(&mut self) -> std::result::Result<(), std::io::Error> {
291            Ok(())
292        }
293    }
294
295    #[test]
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]
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
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
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]
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]
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}