devices/virtio/input/
event_source.rs1use 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
23pub trait EventSource: AsRawDescriptor {
29 fn init(&mut self) -> Result<()> {
31 Ok(())
32 }
33 fn finalize(&mut self) -> Result<()> {
35 Ok(())
36 }
37
38 fn receive_events(&mut self) -> Result<usize>;
42 fn available_events_count(&self) -> usize;
44 fn pop_available_event(&mut self) -> Option<virtio_input_event>;
46 fn send_event(&mut self, vio_evt: &virtio_input_event) -> Result<()>;
48}
49
50pub 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 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 remainder != 0 {
84 warn!("read incomplete event from source");
85 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 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
143pub 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
195pub 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}