1use crate::input_device::{self, InputEvent, UnhandledInputEvent};
6use crate::input_handler::{Handler, InputHandlerStatus, UnhandledInputHandler};
7use crate::keyboard_binding::{KeyboardDeviceDescriptor, KeyboardEvent};
8use anyhow::{Context, Result};
9use async_trait::async_trait;
10use fidl_fuchsia_ui_composition_internal as fcomp;
11use fidl_fuchsia_ui_input3::KeyEventType;
12use fuchsia_async::{OnSignals, Task};
13use fuchsia_inspect::health::Reporter;
14use futures::StreamExt;
15use futures::channel::mpsc::{self, UnboundedReceiver, UnboundedSender};
16use keymaps::KeyState;
17use std::cell::RefCell;
18use std::rc::Rc;
19use std::sync::LazyLock;
20use zx::{AsHandleRef, MonotonicDuration, MonotonicInstant, Signals, Status};
21
22static DISPLAY_OWNED: LazyLock<Signals> = LazyLock::new(|| {
25 Signals::from_bits(fcomp::SIGNAL_DISPLAY_OWNED).expect("static init should not fail")
26});
27
28static DISPLAY_UNOWNED: LazyLock<Signals> = LazyLock::new(|| {
31 Signals::from_bits(fcomp::SIGNAL_DISPLAY_NOT_OWNED).expect("static init should not fail")
32});
33
34static ANY_DISPLAY_EVENT: LazyLock<Signals> = LazyLock::new(|| *DISPLAY_OWNED | *DISPLAY_UNOWNED);
36
37#[derive(Debug, Clone, PartialEq)]
39struct Ownership {
40 signals: Signals,
41}
42
43impl std::convert::From<Signals> for Ownership {
44 fn from(signals: Signals) -> Self {
45 Ownership { signals }
46 }
47}
48
49impl Ownership {
50 fn is_display_ownership_lost(&self) -> bool {
53 self.signals.contains(*DISPLAY_UNOWNED)
54 }
55
56 fn next_signal(&self) -> Signals {
60 match self.is_display_ownership_lost() {
61 true => *DISPLAY_OWNED,
62 false => *DISPLAY_UNOWNED,
63 }
64 }
65
66 async fn wait_ownership_change<'a, T: AsHandleRef>(
71 &self,
72 event: &'a T,
73 ) -> Result<Signals, Status> {
74 OnSignals::new(event, self.next_signal()).await
75 }
76}
77
78pub struct DisplayOwnership {
98 ownership: Rc<RefCell<Ownership>>,
101
102 key_state: RefCell<KeyState>,
104
105 display_ownership_change_receiver: RefCell<Option<UnboundedReceiver<Ownership>>>,
107
108 _display_ownership_task: Task<()>,
111
112 inspect_status: InputHandlerStatus,
114
115 #[cfg(test)]
121 loop_done: RefCell<Option<UnboundedSender<()>>>,
122}
123
124impl DisplayOwnership {
125 pub fn new(
132 display_ownership_event: impl AsHandleRef + 'static,
133 input_handlers_node: &fuchsia_inspect::Node,
134 ) -> Rc<Self> {
135 DisplayOwnership::new_internal(display_ownership_event, None, input_handlers_node)
136 }
137
138 #[cfg(test)]
139 pub fn new_for_test(
140 display_ownership_event: impl AsHandleRef + 'static,
141 loop_done: UnboundedSender<()>,
142 ) -> Rc<Self> {
143 let inspector = fuchsia_inspect::Inspector::default();
144 let fake_handlers_node = inspector.root().create_child("input_handlers_node");
145 DisplayOwnership::new_internal(
146 display_ownership_event,
147 Some(loop_done),
148 &fake_handlers_node,
149 )
150 }
151
152 fn new_internal(
153 display_ownership_event: impl AsHandleRef + 'static,
154 _loop_done: Option<UnboundedSender<()>>,
155 input_handlers_node: &fuchsia_inspect::Node,
156 ) -> Rc<Self> {
157 let initial_state = display_ownership_event
158 .as_handle_ref()
161 .wait_one(*ANY_DISPLAY_EVENT, MonotonicInstant::INFINITE_PAST)
162 .expect("unable to set the initial display state");
163 log::debug!("setting initial display ownership to: {:?}", &initial_state);
164 let initial_ownership: Ownership = initial_state.into();
165 let ownership = Rc::new(RefCell::new(initial_ownership.clone()));
166
167 let mut ownership_clone = initial_ownership;
168 let (ownership_sender, ownership_receiver) = mpsc::unbounded();
169 let display_ownership_task = Task::local(async move {
170 loop {
171 let signals = ownership_clone.wait_ownership_change(&display_ownership_event).await;
172 match signals {
173 Err(e) => {
174 log::warn!("could not read display state: {:?}", e);
175 break;
176 }
177 Ok(signals) => {
178 log::debug!("setting display ownership to: {:?}", &signals);
179 ownership_sender.unbounded_send(signals.into()).unwrap();
180 ownership_clone = signals.into();
181 }
182 }
183 }
184 log::warn!(
185 "display loop exiting and will no longer monitor display changes - this is not expected"
186 );
187 });
188 log::info!("Display ownership handler installed");
189 let inspect_status = InputHandlerStatus::new(
190 input_handlers_node,
191 "display_ownership",
192 false,
193 );
194 Rc::new(Self {
195 ownership,
196 key_state: RefCell::new(KeyState::new()),
197 display_ownership_change_receiver: RefCell::new(Some(ownership_receiver)),
198 _display_ownership_task: display_ownership_task,
199 inspect_status,
200 #[cfg(test)]
201 loop_done: RefCell::new(_loop_done),
202 })
203 }
204
205 fn is_display_ownership_lost(&self) -> bool {
207 self.ownership.borrow().is_display_ownership_lost()
208 }
209
210 pub async fn handle_ownership_change(
217 self: &Rc<Self>,
218 output: UnboundedSender<Vec<InputEvent>>,
219 ) -> Result<()> {
220 let mut ownership_source = self
221 .display_ownership_change_receiver
222 .borrow_mut()
223 .take()
224 .context("display_ownership_change_receiver already taken")?;
225 while let Some(new_ownership) = ownership_source.next().await {
226 let is_display_ownership_lost = new_ownership.is_display_ownership_lost();
227 let event_type = match is_display_ownership_lost {
231 true => KeyEventType::Cancel,
232 false => KeyEventType::Sync,
233 };
234 let keys = self.key_state.borrow().get_set();
235 let mut event_time = MonotonicInstant::get();
236 for key in keys.into_iter() {
237 let key_event = KeyboardEvent::new(key, event_type);
238 output
239 .unbounded_send(vec![into_input_event(key_event, event_time)])
240 .context("unable to send display updates")?;
241 event_time = event_time + MonotonicDuration::from_nanos(1);
242 }
243 *(self.ownership.borrow_mut()) = new_ownership;
244 #[cfg(test)]
245 {
246 if let Some(loop_done) = self.loop_done.borrow().as_ref() {
247 loop_done.unbounded_send(()).unwrap();
248 }
249 }
250 }
251 Ok(())
252 }
253}
254
255impl Handler for DisplayOwnership {
256 fn set_handler_healthy(self: std::rc::Rc<Self>) {
257 self.inspect_status.health_node.borrow_mut().set_ok();
258 }
259
260 fn set_handler_unhealthy(self: std::rc::Rc<Self>, msg: &str) {
261 self.inspect_status.health_node.borrow_mut().set_unhealthy(msg);
262 }
263
264 fn get_name(&self) -> &'static str {
265 "DisplayOwnership"
266 }
267
268 fn interest(&self) -> Vec<input_device::InputEventType> {
269 vec![input_device::InputEventType::Keyboard]
270 }
271}
272
273#[async_trait(?Send)]
274impl UnhandledInputHandler for DisplayOwnership {
275 async fn handle_unhandled_input_event(
276 self: Rc<Self>,
277 unhandled_input_event: UnhandledInputEvent,
278 ) -> Vec<input_device::InputEvent> {
279 fuchsia_trace::duration!("input", "display_ownership");
280 self.inspect_status.count_received_event(&unhandled_input_event.event_time);
281 match unhandled_input_event.device_event {
282 input_device::InputDeviceEvent::Keyboard(ref e) => {
283 self.key_state.borrow_mut().update(e.get_event_type(), e.get_key());
284 }
285 _ => {
286 log::warn!("Unhandled input event: {:?}", unhandled_input_event.get_event_type());
288 }
289 }
290 let is_display_ownership_lost = self.is_display_ownership_lost();
291 if is_display_ownership_lost {
292 self.inspect_status.count_handled_event();
293 }
294
295 #[cfg(test)]
296 {
297 if let Some(loop_done) = self.loop_done.borrow().as_ref() {
298 loop_done.unbounded_send(()).unwrap();
299 }
300 }
301
302 vec![
303 input_device::InputEvent::from(unhandled_input_event)
304 .into_handled_if(is_display_ownership_lost),
305 ]
306 }
307}
308
309fn empty_keyboard_device_descriptor() -> input_device::InputDeviceDescriptor {
310 input_device::InputDeviceDescriptor::Keyboard(
311 KeyboardDeviceDescriptor {
313 keys: vec![],
314 device_information: fidl_fuchsia_input_report::DeviceInformation {
315 vendor_id: Some(0),
316 product_id: Some(0),
317 version: Some(0),
318 polling_rate: Some(0),
319 ..Default::default()
320 },
321 device_id: 0,
322 },
323 )
324}
325
326fn into_input_event(
327 keyboard_event: KeyboardEvent,
328 event_time: MonotonicInstant,
329) -> input_device::InputEvent {
330 input_device::InputEvent {
331 device_event: input_device::InputDeviceEvent::Keyboard(keyboard_event),
332 device_descriptor: empty_keyboard_device_descriptor(),
333 event_time,
334 handled: input_device::Handled::No,
335 trace_id: None,
336 }
337}
338
339#[cfg(test)]
340mod tests {
341 use super::*;
342 use crate::testing_utilities::{create_fake_input_event, create_input_event};
343 use fidl_fuchsia_input::Key;
344 use fuchsia_async as fasync;
345 use pretty_assertions::assert_eq;
346 use std::convert::TryFrom as _;
347 use zx::{EventPair, Peered};
348
349 struct DisplayWrangler {
353 event: EventPair,
354 last: Signals,
355 }
356
357 impl DisplayWrangler {
358 fn new(event: EventPair) -> Self {
359 let mut instance = DisplayWrangler { event, last: *DISPLAY_OWNED };
360 instance.set_unowned();
364 instance
365 }
366
367 fn set_unowned(&mut self) {
368 assert!(self.last != *DISPLAY_UNOWNED, "display is already unowned");
369 self.event.signal_peer(*DISPLAY_OWNED, *DISPLAY_UNOWNED).unwrap();
370 self.last = *DISPLAY_UNOWNED;
371 }
372
373 fn set_owned(&mut self) {
374 assert!(self.last != *DISPLAY_OWNED, "display is already owned");
375 self.event.signal_peer(*DISPLAY_UNOWNED, *DISPLAY_OWNED).unwrap();
376 self.last = *DISPLAY_OWNED;
377 }
378 }
379
380 #[fuchsia::test]
381 async fn display_ownership_change() {
382 let (test_event, handler_event) = EventPair::create();
386
387 let (test_sender, handler_receiver) = mpsc::unbounded::<InputEvent>();
389
390 let (handler_sender, test_receiver) = mpsc::unbounded::<Vec<InputEvent>>();
392
393 let (loop_done_sender, mut loop_done) = mpsc::unbounded::<()>();
396
397 let mut wrangler = DisplayWrangler::new(test_event);
400 let handler = DisplayOwnership::new_for_test(handler_event, loop_done_sender);
401
402 let handler_clone = handler.clone();
403 let handler_sender_clone = handler_sender.clone();
404 let _task = fasync::Task::local(async move {
405 handler_clone.handle_ownership_change(handler_sender_clone).await.unwrap();
406 });
407
408 let handler_clone_2 = handler.clone();
409 let _input_task = fasync::Task::local(async move {
410 let mut receiver = handler_receiver;
411 while let Some(event) = receiver.next().await {
412 let unhandled_event = UnhandledInputEvent::try_from(event).unwrap();
413 let out_events =
414 handler_clone_2.clone().handle_unhandled_input_event(unhandled_event).await;
415 handler_sender.unbounded_send(out_events).unwrap();
416 }
417 });
418
419 let fake_time = MonotonicInstant::from_nanos(42);
420
421 wrangler.set_owned();
425 loop_done.next().await;
426 test_sender.unbounded_send(create_fake_input_event(fake_time)).unwrap();
427 loop_done.next().await;
428
429 wrangler.set_unowned();
431 loop_done.next().await;
432 test_sender.unbounded_send(create_fake_input_event(fake_time)).unwrap();
433 loop_done.next().await;
434
435 wrangler.set_owned();
437 loop_done.next().await;
438 test_sender.unbounded_send(create_fake_input_event(fake_time)).unwrap();
439 loop_done.next().await;
440
441 wrangler.set_unowned();
443 loop_done.next().await;
444 test_sender.unbounded_send(create_fake_input_event(fake_time)).unwrap();
445 loop_done.next().await;
446
447 let actual: Vec<InputEvent> = test_receiver
448 .take(4)
449 .flat_map(|events| futures::stream::iter(events))
450 .map(|e| e.into_with_event_time(fake_time))
451 .collect()
452 .await;
453
454 assert_eq!(
455 actual,
456 vec![
457 create_fake_input_event(fake_time),
459 create_fake_input_event(fake_time).into_handled(),
461 create_fake_input_event(fake_time),
463 create_fake_input_event(fake_time).into_handled(),
465 ]
466 );
467 }
468
469 fn new_keyboard_input_event(key: Key, event_type: KeyEventType) -> InputEvent {
470 let fake_time = MonotonicInstant::from_nanos(42);
471 create_input_event(
472 KeyboardEvent::new(key, event_type),
473 &input_device::InputDeviceDescriptor::Fake,
474 fake_time,
475 input_device::Handled::No,
476 )
477 }
478
479 #[fuchsia::test]
480 async fn basic_key_state_handling() {
481 let (test_event, handler_event) = EventPair::create();
482 let (test_sender, handler_receiver) = mpsc::unbounded::<InputEvent>();
483 let (handler_sender, test_receiver) = mpsc::unbounded::<Vec<InputEvent>>();
484 let (loop_done_sender, mut loop_done) = mpsc::unbounded::<()>();
485 let mut wrangler = DisplayWrangler::new(test_event);
486 let handler = DisplayOwnership::new_for_test(handler_event, loop_done_sender);
487
488 let handler_clone = handler.clone();
489 let handler_sender_clone = handler_sender.clone();
490 let _task = fasync::Task::local(async move {
491 handler_clone.handle_ownership_change(handler_sender_clone).await.unwrap();
492 });
493
494 let handler_clone_2 = handler.clone();
495 let _input_task = fasync::Task::local(async move {
496 let mut receiver = handler_receiver;
497 while let Some(event) = receiver.next().await {
498 let unhandled_event = UnhandledInputEvent::try_from(event).unwrap();
499 let out_events =
500 handler_clone_2.clone().handle_unhandled_input_event(unhandled_event).await;
501 handler_sender.unbounded_send(out_events).unwrap();
502 }
503 });
504
505 let fake_time = MonotonicInstant::from_nanos(42);
506
507 wrangler.set_owned();
509 loop_done.next().await;
510 test_sender
511 .unbounded_send(new_keyboard_input_event(Key::A, KeyEventType::Pressed))
512 .unwrap();
513 loop_done.next().await;
514
515 wrangler.set_unowned();
517 loop_done.next().await;
518
519 wrangler.set_owned();
521 loop_done.next().await;
522
523 test_sender
525 .unbounded_send(new_keyboard_input_event(Key::A, KeyEventType::Released))
526 .unwrap();
527 loop_done.next().await;
528
529 let actual: Vec<InputEvent> = test_receiver
530 .take(4)
531 .flat_map(|events| futures::stream::iter(events))
532 .map(|e| e.into_with_event_time(fake_time))
533 .collect()
534 .await;
535
536 assert_eq!(
537 actual,
538 vec![
539 new_keyboard_input_event(Key::A, KeyEventType::Pressed),
540 new_keyboard_input_event(Key::A, KeyEventType::Cancel)
541 .into_with_device_descriptor(empty_keyboard_device_descriptor()),
542 new_keyboard_input_event(Key::A, KeyEventType::Sync)
543 .into_with_device_descriptor(empty_keyboard_device_descriptor()),
544 new_keyboard_input_event(Key::A, KeyEventType::Released),
545 ]
546 );
547 }
548
549 #[fuchsia::test]
550 async fn more_key_state_handling() {
551 let (test_event, handler_event) = EventPair::create();
552 let (test_sender, handler_receiver) = mpsc::unbounded::<InputEvent>();
553 let (handler_sender, test_receiver) = mpsc::unbounded::<Vec<InputEvent>>();
554 let (loop_done_sender, mut loop_done) = mpsc::unbounded::<()>();
555 let mut wrangler = DisplayWrangler::new(test_event);
556 let handler = DisplayOwnership::new_for_test(handler_event, loop_done_sender);
557
558 let handler_clone = handler.clone();
559 let handler_sender_clone = handler_sender.clone();
560 let _task = fasync::Task::local(async move {
561 handler_clone.handle_ownership_change(handler_sender_clone).await.unwrap();
562 });
563
564 let handler_clone_2 = handler.clone();
565 let _input_task = fasync::Task::local(async move {
566 let mut receiver = handler_receiver;
567 while let Some(event) = receiver.next().await {
568 let unhandled_event = UnhandledInputEvent::try_from(event).unwrap();
569 let out_events =
570 handler_clone_2.clone().handle_unhandled_input_event(unhandled_event).await;
571 handler_sender.unbounded_send(out_events).unwrap();
572 }
573 });
574
575 let fake_time = MonotonicInstant::from_nanos(42);
576
577 wrangler.set_owned();
578 loop_done.next().await;
579 test_sender
580 .unbounded_send(new_keyboard_input_event(Key::A, KeyEventType::Pressed))
581 .unwrap();
582 loop_done.next().await;
583 test_sender
584 .unbounded_send(new_keyboard_input_event(Key::B, KeyEventType::Pressed))
585 .unwrap();
586 loop_done.next().await;
587
588 wrangler.set_unowned();
590 loop_done.next().await;
591 test_sender
592 .unbounded_send(new_keyboard_input_event(Key::B, KeyEventType::Released))
593 .unwrap();
594 loop_done.next().await;
595 test_sender
596 .unbounded_send(new_keyboard_input_event(Key::C, KeyEventType::Pressed))
597 .unwrap();
598 loop_done.next().await;
599
600 wrangler.set_owned();
602 loop_done.next().await;
603
604 test_sender
606 .unbounded_send(new_keyboard_input_event(Key::A, KeyEventType::Released))
607 .unwrap();
608 loop_done.next().await;
609 test_sender
610 .unbounded_send(new_keyboard_input_event(Key::C, KeyEventType::Released))
611 .unwrap();
612 loop_done.next().await;
613
614 let actual: Vec<InputEvent> = test_receiver
615 .take(10) .flat_map(|events| futures::stream::iter(events))
617 .map(|e| e.into_with_event_time(fake_time))
618 .collect()
619 .await;
620
621 assert_eq!(
622 actual,
623 vec![
624 new_keyboard_input_event(Key::A, KeyEventType::Pressed),
625 new_keyboard_input_event(Key::B, KeyEventType::Pressed),
626 new_keyboard_input_event(Key::A, KeyEventType::Cancel)
627 .into_with_device_descriptor(empty_keyboard_device_descriptor()),
628 new_keyboard_input_event(Key::B, KeyEventType::Cancel)
629 .into_with_device_descriptor(empty_keyboard_device_descriptor()),
630 new_keyboard_input_event(Key::B, KeyEventType::Released).into_handled(),
631 new_keyboard_input_event(Key::C, KeyEventType::Pressed).into_handled(),
632 new_keyboard_input_event(Key::A, KeyEventType::Sync)
636 .into_with_device_descriptor(empty_keyboard_device_descriptor()),
637 new_keyboard_input_event(Key::C, KeyEventType::Sync)
638 .into_with_device_descriptor(empty_keyboard_device_descriptor()),
639 new_keyboard_input_event(Key::A, KeyEventType::Released),
640 new_keyboard_input_event(Key::C, KeyEventType::Released),
641 ]
642 );
643 }
644
645 #[fuchsia::test]
646 async fn display_ownership_initialized_with_inspect_node() {
647 let (test_event, handler_event) = EventPair::create();
648 let (loop_done_sender, _) = mpsc::unbounded::<()>();
649 let inspector = fuchsia_inspect::Inspector::default();
650 let fake_handlers_node = inspector.root().create_child("input_handlers_node");
651 let _ = DisplayWrangler::new(test_event);
653 let _handler = DisplayOwnership::new_internal(
654 handler_event,
655 Some(loop_done_sender),
656 &fake_handlers_node,
657 );
658 diagnostics_assertions::assert_data_tree!(inspector, root: {
659 input_handlers_node: {
660 display_ownership: {
661 events_received_count: 0u64,
662 events_handled_count: 0u64,
663 last_received_timestamp_ns: 0u64,
664 "fuchsia.inspect.Health": {
665 status: "STARTING_UP",
666 start_timestamp_nanos: diagnostics_assertions::AnyProperty
669 },
670 }
671 }
672 });
673 }
674
675 #[fuchsia::test]
676 async fn display_ownership_inspect_counts_events() {
677 let (test_event, handler_event) = EventPair::create();
678 let (test_sender, handler_receiver) = mpsc::unbounded::<InputEvent>();
679 let (handler_sender, _test_receiver) = mpsc::unbounded::<Vec<InputEvent>>();
680 let (loop_done_sender, mut loop_done) = mpsc::unbounded::<()>();
681 let mut wrangler = DisplayWrangler::new(test_event);
682 let inspector = fuchsia_inspect::Inspector::default();
683 let fake_handlers_node = inspector.root().create_child("input_handlers_node");
684 let handler = DisplayOwnership::new_internal(
685 handler_event,
686 Some(loop_done_sender),
687 &fake_handlers_node,
688 );
689 let handler_clone = handler.clone();
690 let handler_sender_clone = handler_sender.clone();
691 let _task = fasync::Task::local(async move {
692 handler_clone.handle_ownership_change(handler_sender_clone).await.unwrap();
693 });
694
695 let handler_clone_2 = handler.clone();
696 let _input_task = fasync::Task::local(async move {
697 let mut receiver = handler_receiver;
698 while let Some(event) = receiver.next().await {
699 let unhandled_event = UnhandledInputEvent::try_from(event).unwrap();
700 let out_events =
701 handler_clone_2.clone().handle_unhandled_input_event(unhandled_event).await;
702 handler_sender.unbounded_send(out_events).unwrap();
703 }
704 });
705
706 wrangler.set_owned();
708 loop_done.next().await;
709 test_sender
710 .unbounded_send(new_keyboard_input_event(Key::A, KeyEventType::Pressed))
711 .unwrap();
712 loop_done.next().await;
713
714 wrangler.set_unowned();
717 loop_done.next().await;
718 test_sender
719 .unbounded_send(new_keyboard_input_event(Key::B, KeyEventType::Pressed))
720 .unwrap();
721 loop_done.next().await;
722
723 wrangler.set_owned();
725 loop_done.next().await;
726
727 test_sender
729 .unbounded_send(new_keyboard_input_event(Key::A, KeyEventType::Released))
730 .unwrap();
731 loop_done.next().await;
732
733 diagnostics_assertions::assert_data_tree!(inspector, root: {
734 input_handlers_node: {
735 display_ownership: {
736 events_received_count: 3u64,
737 events_handled_count: 1u64,
738 last_received_timestamp_ns: 42u64,
739 "fuchsia.inspect.Health": {
740 status: "STARTING_UP",
741 start_timestamp_nanos: diagnostics_assertions::AnyProperty
744 },
745 }
746 }
747 });
748 }
749}