Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
google
GitHub Repository: google/crosvm
Path: blob/main/devices/src/virtio/input/event_source.rs
5394 views
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::IntoBytes;
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.
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.
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> {
59
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.
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
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
{
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> {
160
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
{
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
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
{
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> {
212
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
{
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)]
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::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
}
389
390