1use crate::input_device::{self, InputEvent, UnhandledInputEvent};
6use crate::input_handler::{Handler, InputHandlerStatus, UnhandledInputHandler};
7use crate::keyboard_binding::{KeyboardDeviceDescriptor, KeyboardEvent};
8use crate::metrics;
9use anyhow::{Context, Result};
10use async_trait::async_trait;
11use fidl_fuchsia_ui_input_internal as finput;
12use fidl_fuchsia_ui_input3::KeyEventType;
13use fuchsia_async::{OnSignals, Task};
14use fuchsia_inspect::health::Reporter;
15use futures::StreamExt;
16use futures::channel::mpsc::{self, UnboundedReceiver, UnboundedSender};
17use futures::future::LocalBoxFuture;
18use keymaps::KeyState;
19use metrics_registry::InputPipelineErrorMetricDimensionEvent;
20use std::cell::RefCell;
21use std::rc::Rc;
22use std::sync::LazyLock;
23use zx::{
24 AsHandleRef, MonotonicDuration, MonotonicInstant, NullableHandle, Rights, Signals, Status,
25 WaitResult,
26};
27
28pub static DISPLAY_UNOWNED: LazyLock<Signals> = LazyLock::new(|| {
30 Signals::from_bits(finput::InputOwnershipSignal::DISPLAY_UNOWNED.bits())
31 .expect("static init should not fail")
32});
33
34pub static DISPLAY_PLATFORM_OWNED: LazyLock<Signals> = LazyLock::new(|| {
36 Signals::from_bits(finput::InputOwnershipSignal::DISPLAY_PLATFORM_OWNED.bits())
37 .expect("static init should not fail")
38});
39
40pub static INPUT_CLIENT_OWNED: LazyLock<Signals> = LazyLock::new(|| {
42 Signals::from_bits(finput::InputOwnershipSignal::INPUT_CLIENT_OWNED.bits())
43 .expect("static init should not fail")
44});
45
46pub static INPUT_PLATFORM_OWNED: LazyLock<Signals> = LazyLock::new(|| {
48 Signals::from_bits(finput::InputOwnershipSignal::INPUT_PLATFORM_OWNED.bits())
49 .expect("static init should not fail")
50});
51
52pub static ANY_OWNERSHIP_SIGNAL: LazyLock<Signals> = LazyLock::new(|| {
54 *DISPLAY_UNOWNED | *DISPLAY_PLATFORM_OWNED | *INPUT_CLIENT_OWNED | *INPUT_PLATFORM_OWNED
55});
56
57#[derive(Debug, Clone, PartialEq)]
59pub struct Ownership {
60 pub signals: Signals,
61}
62
63impl std::convert::From<Signals> for Ownership {
64 fn from(signals: Signals) -> Self {
65 Ownership { signals }
66 }
67}
68
69impl Ownership {
70 pub fn is_display_ownership_lost(&self) -> bool {
72 Self::is_signals_ownership_lost(self.signals)
73 }
74
75 pub fn is_signals_ownership_lost(signals: Signals) -> bool {
82 if signals.contains(Signals::OBJECT_PEER_CLOSED) {
83 return true;
84 }
85 let has_input_signals =
86 signals.contains(*INPUT_CLIENT_OWNED) || signals.contains(*INPUT_PLATFORM_OWNED);
87 let input_owned = if has_input_signals {
88 signals.contains(*INPUT_PLATFORM_OWNED) && !signals.contains(*INPUT_CLIENT_OWNED)
89 } else {
90 true
92 };
93 let display_owned =
94 signals.contains(*DISPLAY_PLATFORM_OWNED) && !signals.contains(*DISPLAY_UNOWNED);
95 !(display_owned && input_owned)
96 }
97
98 fn read_current_signals<T: AsHandleRef>(event: &T) -> Result<Signals, Status> {
99 match event.as_handle_ref().wait_one(Signals::empty(), MonotonicInstant::INFINITE_PAST) {
100 WaitResult::Ok(signals) | WaitResult::TimedOut(signals) => Ok(signals),
101 WaitResult::Canceled(signals) => Ok(signals),
102 WaitResult::Err(Status::PEER_CLOSED) => Ok(Signals::OBJECT_PEER_CLOSED),
103 WaitResult::Err(status) => Err(status),
104 }
105 }
106
107 pub async fn wait_ownership_change<T: AsHandleRef>(
115 &self,
116 event: &T,
117 ) -> Result<Signals, Status> {
118 let currently_lost = self.is_display_ownership_lost();
119 loop {
120 let wait_signals = if !currently_lost {
121 *DISPLAY_UNOWNED | *INPUT_CLIENT_OWNED | Signals::OBJECT_PEER_CLOSED
122 } else {
123 let cur = Self::read_current_signals(event)?;
124 if cur.contains(Signals::OBJECT_PEER_CLOSED) {
125 return Err(Status::PEER_CLOSED);
126 }
127 if !Self::is_signals_ownership_lost(cur) {
128 return Ok(cur);
129 }
130 let missing_display = !cur.contains(*DISPLAY_PLATFORM_OWNED);
131 let has_input_signals =
132 cur.contains(*INPUT_CLIENT_OWNED) || cur.contains(*INPUT_PLATFORM_OWNED);
133 let missing_input =
134 if has_input_signals { !cur.contains(*INPUT_PLATFORM_OWNED) } else { false };
135
136 let mut signals_to_wait = Signals::OBJECT_PEER_CLOSED;
137 if missing_display && missing_input {
138 signals_to_wait |= *DISPLAY_PLATFORM_OWNED | *INPUT_PLATFORM_OWNED;
139 } else if missing_display {
140 signals_to_wait |= *DISPLAY_PLATFORM_OWNED;
141 } else if missing_input {
142 signals_to_wait |= *INPUT_PLATFORM_OWNED;
143 } else {
144 log::error!(
145 "display_ownership: peer asserted invalid contradictory signals (ownership lost but neither platform signal missing): {:?}",
146 cur
147 );
148 return Err(Status::BAD_STATE);
149 }
150 signals_to_wait
151 };
152
153 OnSignals::new(event, wait_signals).await?;
154
155 let cur = Self::read_current_signals(event)?;
156 if currently_lost && cur.contains(Signals::OBJECT_PEER_CLOSED) {
157 return Err(Status::PEER_CLOSED);
158 }
159 let new_lost = Self::is_signals_ownership_lost(cur);
160 if new_lost != currently_lost {
161 return Ok(cur);
162 }
163 if cur.contains(Signals::OBJECT_PEER_CLOSED) {
164 return Err(Status::PEER_CLOSED);
165 }
166 }
167 }
168}
169
170type OwnershipChangeCallback = Rc<dyn Fn(bool) -> LocalBoxFuture<'static, ()>>;
171
172pub struct DisplayOwnership {
193 ownership: Rc<RefCell<Ownership>>,
196
197 key_state: RefCell<KeyState>,
199
200 display_ownership_change_receiver: RefCell<Option<UnboundedReceiver<Ownership>>>,
202
203 ownership_change_callback: RefCell<Option<OwnershipChangeCallback>>,
206
207 _display_ownership_task: Task<()>,
210
211 metrics_logger: metrics::MetricsLogger,
213
214 inspect_status: InputHandlerStatus,
216
217 #[cfg(test)]
223 loop_done: RefCell<Option<UnboundedSender<()>>>,
224 display_ownership_event: NullableHandle,
225}
226
227impl DisplayOwnership {
228 pub fn new(
233 display_ownership_event: impl AsHandleRef + 'static,
234 input_handlers_node: &fuchsia_inspect::Node,
235 metrics_logger: metrics::MetricsLogger,
236 ) -> Rc<Self> {
237 DisplayOwnership::new_internal(
238 display_ownership_event,
239 None,
240 input_handlers_node,
241 metrics_logger,
242 )
243 }
244
245 #[cfg(test)]
246 pub fn new_for_test(
247 display_ownership_event: impl AsHandleRef + 'static,
248 loop_done: UnboundedSender<()>,
249 metrics_logger: metrics::MetricsLogger,
250 ) -> Rc<Self> {
251 let inspector = fuchsia_inspect::Inspector::default();
252 let fake_handlers_node = inspector.root().create_child("input_handlers_node");
253 DisplayOwnership::new_internal(
254 display_ownership_event,
255 Some(loop_done),
256 &fake_handlers_node,
257 metrics_logger,
258 )
259 }
260
261 fn new_internal(
262 display_ownership_event: impl AsHandleRef + 'static,
263 _loop_done: Option<UnboundedSender<()>>,
264 input_handlers_node: &fuchsia_inspect::Node,
265 metrics_logger: metrics::MetricsLogger,
266 ) -> Rc<Self> {
267 let event_handle = display_ownership_event
268 .as_handle_ref()
269 .duplicate_handle(Rights::SAME_RIGHTS)
270 .expect("unable to duplicate display ownership event");
271 let initial_state = match display_ownership_event
272 .as_handle_ref()
273 .wait_one(*ANY_OWNERSHIP_SIGNAL, MonotonicInstant::INFINITE_PAST)
274 {
275 WaitResult::Ok(signals) | WaitResult::TimedOut(signals) => signals,
276 WaitResult::Canceled(signals) => signals,
277 WaitResult::Err(e) => panic!("unable to set the initial display state: {:?}", e),
278 };
279 log::debug!("setting initial display ownership to: {:?}", initial_state);
280 let initial_ownership: Ownership = initial_state.into();
281 let ownership = Rc::new(RefCell::new(initial_ownership.clone()));
282
283 let mut ownership_clone = initial_ownership;
284 let (ownership_sender, ownership_receiver) = mpsc::unbounded();
285 let display_ownership_task = Task::local(async move {
286 loop {
287 let signals = ownership_clone.wait_ownership_change(&display_ownership_event).await;
288 match signals {
289 Err(e) => {
290 log::warn!("could not read display state: {:?}", e);
291 break;
292 }
293 Ok(signals) => {
294 log::debug!("setting display ownership to: {:?}", signals);
295 ownership_sender.unbounded_send(signals.into()).unwrap();
296 ownership_clone = signals.into();
297 }
298 }
299 }
300 log::warn!(
301 "display loop exiting and will no longer monitor display changes - this is not expected"
302 );
303 });
304 log::info!("Display ownership handler installed");
305 let inspect_status = InputHandlerStatus::new(
306 input_handlers_node,
307 "display_ownership",
308 false,
309 );
310 Rc::new(Self {
311 ownership,
312 key_state: RefCell::new(KeyState::new()),
313 display_ownership_change_receiver: RefCell::new(Some(ownership_receiver)),
314 ownership_change_callback: RefCell::new(None),
315 _display_ownership_task: display_ownership_task,
316 metrics_logger,
317 inspect_status,
318 #[cfg(test)]
319 loop_done: RefCell::new(_loop_done),
320 display_ownership_event: event_handle,
321 })
322 }
323
324 pub fn set_ownership_change_callback(
328 &self,
329 callback: impl Fn(bool) -> LocalBoxFuture<'static, ()> + 'static,
330 ) {
331 *self.ownership_change_callback.borrow_mut() = Some(Rc::new(callback));
332 }
333
334 pub fn is_display_ownership_lost(&self) -> bool {
336 match self
341 .display_ownership_event
342 .wait_one(Signals::empty(), MonotonicInstant::INFINITE_PAST)
343 {
344 WaitResult::Ok(signals) | WaitResult::TimedOut(signals) => {
345 Ownership::is_signals_ownership_lost(signals)
346 }
347 WaitResult::Err(Status::PEER_CLOSED) | WaitResult::Canceled(_) => true,
348 WaitResult::Err(e) => {
349 log::error!("Unexpected error on display ownership event: {:?}", e);
350 self.ownership.borrow().is_display_ownership_lost()
351 }
352 }
353 }
354
355 pub async fn handle_ownership_change(
362 self: &Rc<Self>,
363 output: UnboundedSender<Vec<InputEvent>>,
364 ) -> Result<()> {
365 let mut ownership_source = self
366 .display_ownership_change_receiver
367 .borrow_mut()
368 .take()
369 .context("display_ownership_change_receiver already taken")?;
370 while let Some(new_ownership) = ownership_source.next().await {
371 let was_ownership_lost = self.ownership.borrow().is_display_ownership_lost();
372 let is_display_ownership_lost = new_ownership.is_display_ownership_lost();
373 let event_type = match is_display_ownership_lost {
377 true => KeyEventType::Cancel,
378 false => KeyEventType::Sync,
379 };
380 let keys = self.key_state.borrow().get_set();
381 let mut event_time = MonotonicInstant::get();
382 for key in keys.into_iter() {
383 let key_event = KeyboardEvent::new(key, event_type);
384 output
385 .unbounded_send(vec![into_input_event(key_event, event_time)])
386 .context("unable to send display updates")?;
387 event_time = event_time + MonotonicDuration::from_nanos(1);
388 }
389 *(self.ownership.borrow_mut()) = new_ownership;
390 if was_ownership_lost != is_display_ownership_lost {
391 let callback = self.ownership_change_callback.borrow().clone();
392 if let Some(cb) = callback {
393 cb(!is_display_ownership_lost).await;
394 }
395 }
396 #[cfg(test)]
397 {
398 if let Some(loop_done) = self.loop_done.borrow().as_ref() {
399 loop_done.unbounded_send(()).unwrap();
400 }
401 }
402 }
403 Ok(())
404 }
405}
406
407impl Handler for DisplayOwnership {
408 fn set_handler_healthy(self: std::rc::Rc<Self>) {
409 self.inspect_status.health_node.borrow_mut().set_ok();
410 }
411
412 fn set_handler_unhealthy(self: std::rc::Rc<Self>, msg: &str) {
413 self.inspect_status.health_node.borrow_mut().set_unhealthy(msg);
414 }
415
416 fn get_name(&self) -> &'static str {
417 "DisplayOwnership"
418 }
419
420 fn interest(&self) -> Vec<input_device::InputEventType> {
421 vec![input_device::InputEventType::Keyboard]
422 }
423}
424
425#[async_trait(?Send)]
426impl UnhandledInputHandler for DisplayOwnership {
427 async fn handle_unhandled_input_event(
428 self: Rc<Self>,
429 unhandled_input_event: UnhandledInputEvent,
430 ) -> Vec<input_device::InputEvent> {
431 fuchsia_trace::duration!("input", "display_ownership");
432 self.inspect_status.count_received_event(&unhandled_input_event.event_time);
433 match unhandled_input_event.device_event {
434 input_device::InputDeviceEvent::Keyboard(ref e) => {
435 self.key_state.borrow_mut().update(e.get_event_type(), e.get_key());
436 }
437 _ => {
438 self.metrics_logger.log_error(
439 InputPipelineErrorMetricDimensionEvent::HandlerReceivedUninterestedEvent,
440 std::format!(
441 "{} uninterested input event: {:?}",
442 self.get_name(),
443 unhandled_input_event.get_event_type()
444 ),
445 );
446 }
447 }
448 let is_display_ownership_lost = self.is_display_ownership_lost();
449 if is_display_ownership_lost {
450 self.inspect_status.count_handled_event();
451 }
452
453 #[cfg(test)]
454 {
455 if let Some(loop_done) = self.loop_done.borrow().as_ref() {
456 loop_done.unbounded_send(()).unwrap();
457 }
458 }
459
460 vec![
461 input_device::InputEvent::from(unhandled_input_event)
462 .into_handled_if(is_display_ownership_lost),
463 ]
464 }
465}
466
467fn empty_keyboard_device_descriptor() -> input_device::InputDeviceDescriptor {
468 input_device::InputDeviceDescriptor::Keyboard(
469 KeyboardDeviceDescriptor {
471 keys: vec![],
472 device_information: fidl_fuchsia_input_report::DeviceInformation {
473 vendor_id: Some(0),
474 product_id: Some(0),
475 version: Some(0),
476 polling_rate: Some(0),
477 ..Default::default()
478 },
479 device_id: 0,
480 },
481 )
482}
483
484fn into_input_event(
485 keyboard_event: KeyboardEvent,
486 event_time: MonotonicInstant,
487) -> input_device::InputEvent {
488 input_device::InputEvent {
489 device_event: input_device::InputDeviceEvent::Keyboard(keyboard_event),
490 device_descriptor: empty_keyboard_device_descriptor(),
491 event_time,
492 handled: input_device::Handled::No,
493 trace_id: None,
494 }
495}
496
497#[cfg(test)]
498mod tests {
499 use super::*;
500 use crate::testing_utilities::{create_fake_input_event, create_input_event};
501 use fidl_fuchsia_input::Key;
502 use fuchsia_async as fasync;
503 use pretty_assertions::assert_eq;
504 use std::convert::TryFrom as _;
505 use zx::{EventPair, Peered};
506
507 struct DisplayWrangler {
511 event: EventPair,
512 last_display: Signals,
513 last_input: Signals,
514 }
515
516 impl DisplayWrangler {
517 fn new(event: EventPair) -> Self {
518 let mut instance = DisplayWrangler {
519 event,
520 last_display: *DISPLAY_PLATFORM_OWNED,
521 last_input: *INPUT_PLATFORM_OWNED,
522 };
523 instance
526 .event
527 .signal_peer(Signals::empty(), *DISPLAY_UNOWNED | *INPUT_PLATFORM_OWNED)
528 .unwrap();
529 instance.last_display = *DISPLAY_UNOWNED;
530 instance.last_input = *INPUT_PLATFORM_OWNED;
531 instance
532 }
533
534 fn set_unowned(&mut self) {
535 assert!(self.last_display != *DISPLAY_UNOWNED, "display is already unowned");
536 self.event.signal_peer(*DISPLAY_PLATFORM_OWNED, *DISPLAY_UNOWNED).unwrap();
537 self.last_display = *DISPLAY_UNOWNED;
538 }
539
540 fn set_owned(&mut self) {
541 assert!(self.last_display != *DISPLAY_PLATFORM_OWNED, "display is already owned");
542 self.event.signal_peer(*DISPLAY_UNOWNED, *DISPLAY_PLATFORM_OWNED).unwrap();
543 self.last_display = *DISPLAY_PLATFORM_OWNED;
544 }
545
546 fn set_client_input_owned(&mut self) {
547 assert!(self.last_input != *INPUT_CLIENT_OWNED, "input is already client owned");
548 self.event.signal_peer(*INPUT_PLATFORM_OWNED, *INPUT_CLIENT_OWNED).unwrap();
549 self.last_input = *INPUT_CLIENT_OWNED;
550 }
551
552 fn set_platform_input_owned(&mut self) {
553 assert!(self.last_input != *INPUT_PLATFORM_OWNED, "input is already platform owned");
554 self.event.signal_peer(*INPUT_CLIENT_OWNED, *INPUT_PLATFORM_OWNED).unwrap();
555 self.last_input = *INPUT_PLATFORM_OWNED;
556 }
557 }
558
559 #[fuchsia::test]
560 async fn display_ownership_change() {
561 let (test_event, handler_event) = EventPair::create();
565
566 let (test_sender, handler_receiver) = mpsc::unbounded::<InputEvent>();
568
569 let (handler_sender, test_receiver) = mpsc::unbounded::<Vec<InputEvent>>();
571
572 let (loop_done_sender, mut loop_done) = mpsc::unbounded::<()>();
575
576 let mut wrangler = DisplayWrangler::new(test_event);
579 let handler = DisplayOwnership::new_for_test(
580 handler_event,
581 loop_done_sender,
582 metrics::MetricsLogger::default(),
583 );
584
585 let handler_clone = handler.clone();
586 let handler_sender_clone = handler_sender.clone();
587 let _task = fasync::Task::local(async move {
588 handler_clone.handle_ownership_change(handler_sender_clone).await.unwrap();
589 });
590
591 let handler_clone_2 = handler.clone();
592 let _input_task = fasync::Task::local(async move {
593 let mut receiver = handler_receiver;
594 while let Some(event) = receiver.next().await {
595 let unhandled_event = UnhandledInputEvent::try_from(event).unwrap();
596 let out_events =
597 handler_clone_2.clone().handle_unhandled_input_event(unhandled_event).await;
598 handler_sender.unbounded_send(out_events).unwrap();
599 }
600 });
601
602 let fake_time = MonotonicInstant::from_nanos(42);
603
604 wrangler.set_owned();
608 loop_done.next().await;
609 test_sender.unbounded_send(create_fake_input_event(fake_time)).unwrap();
610 loop_done.next().await;
611
612 wrangler.set_unowned();
614 loop_done.next().await;
615 test_sender.unbounded_send(create_fake_input_event(fake_time)).unwrap();
616 loop_done.next().await;
617
618 wrangler.set_owned();
620 loop_done.next().await;
621 test_sender.unbounded_send(create_fake_input_event(fake_time)).unwrap();
622 loop_done.next().await;
623
624 wrangler.set_unowned();
626 loop_done.next().await;
627 test_sender.unbounded_send(create_fake_input_event(fake_time)).unwrap();
628 loop_done.next().await;
629
630 let actual: Vec<InputEvent> = test_receiver
631 .take(4)
632 .flat_map(|events| futures::stream::iter(events))
633 .map(|e| e.into_with_event_time(fake_time))
634 .collect()
635 .await;
636
637 assert_eq!(
638 actual,
639 vec![
640 create_fake_input_event(fake_time),
642 create_fake_input_event(fake_time).into_handled(),
644 create_fake_input_event(fake_time),
646 create_fake_input_event(fake_time).into_handled(),
648 ]
649 );
650 }
651
652 fn new_keyboard_input_event(key: Key, event_type: KeyEventType) -> InputEvent {
653 let fake_time = MonotonicInstant::from_nanos(42);
654 create_input_event(
655 KeyboardEvent::new(key, event_type),
656 &input_device::InputDeviceDescriptor::Fake,
657 fake_time,
658 input_device::Handled::No,
659 )
660 }
661
662 #[fuchsia::test]
663 async fn basic_key_state_handling() {
664 let (test_event, handler_event) = EventPair::create();
665 let (test_sender, handler_receiver) = mpsc::unbounded::<InputEvent>();
666 let (handler_sender, test_receiver) = mpsc::unbounded::<Vec<InputEvent>>();
667 let (loop_done_sender, mut loop_done) = mpsc::unbounded::<()>();
668 let mut wrangler = DisplayWrangler::new(test_event);
669 let handler = DisplayOwnership::new_for_test(
670 handler_event,
671 loop_done_sender,
672 metrics::MetricsLogger::default(),
673 );
674
675 let handler_clone = handler.clone();
676 let handler_sender_clone = handler_sender.clone();
677 let _task = fasync::Task::local(async move {
678 handler_clone.handle_ownership_change(handler_sender_clone).await.unwrap();
679 });
680
681 let handler_clone_2 = handler.clone();
682 let _input_task = fasync::Task::local(async move {
683 let mut receiver = handler_receiver;
684 while let Some(event) = receiver.next().await {
685 let unhandled_event = UnhandledInputEvent::try_from(event).unwrap();
686 let out_events =
687 handler_clone_2.clone().handle_unhandled_input_event(unhandled_event).await;
688 handler_sender.unbounded_send(out_events).unwrap();
689 }
690 });
691
692 let fake_time = MonotonicInstant::from_nanos(42);
693
694 wrangler.set_owned();
696 loop_done.next().await;
697 test_sender
698 .unbounded_send(new_keyboard_input_event(Key::A, KeyEventType::Pressed))
699 .unwrap();
700 loop_done.next().await;
701
702 wrangler.set_unowned();
704 loop_done.next().await;
705
706 wrangler.set_owned();
708 loop_done.next().await;
709
710 test_sender
712 .unbounded_send(new_keyboard_input_event(Key::A, KeyEventType::Released))
713 .unwrap();
714 loop_done.next().await;
715
716 let actual: Vec<InputEvent> = test_receiver
717 .take(4)
718 .flat_map(|events| futures::stream::iter(events))
719 .map(|e| e.into_with_event_time(fake_time))
720 .collect()
721 .await;
722
723 assert_eq!(
724 actual,
725 vec![
726 new_keyboard_input_event(Key::A, KeyEventType::Pressed),
727 new_keyboard_input_event(Key::A, KeyEventType::Cancel)
728 .into_with_device_descriptor(empty_keyboard_device_descriptor()),
729 new_keyboard_input_event(Key::A, KeyEventType::Sync)
730 .into_with_device_descriptor(empty_keyboard_device_descriptor()),
731 new_keyboard_input_event(Key::A, KeyEventType::Released),
732 ]
733 );
734 }
735
736 #[fuchsia::test]
737 async fn more_key_state_handling() {
738 let (test_event, handler_event) = EventPair::create();
739 let (test_sender, handler_receiver) = mpsc::unbounded::<InputEvent>();
740 let (handler_sender, test_receiver) = mpsc::unbounded::<Vec<InputEvent>>();
741 let (loop_done_sender, mut loop_done) = mpsc::unbounded::<()>();
742 let mut wrangler = DisplayWrangler::new(test_event);
743 let handler = DisplayOwnership::new_for_test(
744 handler_event,
745 loop_done_sender,
746 metrics::MetricsLogger::default(),
747 );
748
749 let handler_clone = handler.clone();
750 let handler_sender_clone = handler_sender.clone();
751 let _task = fasync::Task::local(async move {
752 handler_clone.handle_ownership_change(handler_sender_clone).await.unwrap();
753 });
754
755 let handler_clone_2 = handler.clone();
756 let _input_task = fasync::Task::local(async move {
757 let mut receiver = handler_receiver;
758 while let Some(event) = receiver.next().await {
759 let unhandled_event = UnhandledInputEvent::try_from(event).unwrap();
760 let out_events =
761 handler_clone_2.clone().handle_unhandled_input_event(unhandled_event).await;
762 handler_sender.unbounded_send(out_events).unwrap();
763 }
764 });
765
766 let fake_time = MonotonicInstant::from_nanos(42);
767
768 wrangler.set_owned();
769 loop_done.next().await;
770 test_sender
771 .unbounded_send(new_keyboard_input_event(Key::A, KeyEventType::Pressed))
772 .unwrap();
773 loop_done.next().await;
774 test_sender
775 .unbounded_send(new_keyboard_input_event(Key::B, KeyEventType::Pressed))
776 .unwrap();
777 loop_done.next().await;
778
779 wrangler.set_unowned();
781 loop_done.next().await;
782 test_sender
783 .unbounded_send(new_keyboard_input_event(Key::B, KeyEventType::Released))
784 .unwrap();
785 loop_done.next().await;
786 test_sender
787 .unbounded_send(new_keyboard_input_event(Key::C, KeyEventType::Pressed))
788 .unwrap();
789 loop_done.next().await;
790
791 wrangler.set_owned();
793 loop_done.next().await;
794
795 test_sender
797 .unbounded_send(new_keyboard_input_event(Key::A, KeyEventType::Released))
798 .unwrap();
799 loop_done.next().await;
800 test_sender
801 .unbounded_send(new_keyboard_input_event(Key::C, KeyEventType::Released))
802 .unwrap();
803 loop_done.next().await;
804
805 let actual: Vec<InputEvent> = test_receiver
806 .take(10) .flat_map(|events| futures::stream::iter(events))
808 .map(|e| e.into_with_event_time(fake_time))
809 .collect()
810 .await;
811
812 assert_eq!(
813 actual,
814 vec![
815 new_keyboard_input_event(Key::A, KeyEventType::Pressed),
816 new_keyboard_input_event(Key::B, KeyEventType::Pressed),
817 new_keyboard_input_event(Key::A, KeyEventType::Cancel)
818 .into_with_device_descriptor(empty_keyboard_device_descriptor()),
819 new_keyboard_input_event(Key::B, KeyEventType::Cancel)
820 .into_with_device_descriptor(empty_keyboard_device_descriptor()),
821 new_keyboard_input_event(Key::B, KeyEventType::Released).into_handled(),
822 new_keyboard_input_event(Key::C, KeyEventType::Pressed).into_handled(),
823 new_keyboard_input_event(Key::A, KeyEventType::Sync)
827 .into_with_device_descriptor(empty_keyboard_device_descriptor()),
828 new_keyboard_input_event(Key::C, KeyEventType::Sync)
829 .into_with_device_descriptor(empty_keyboard_device_descriptor()),
830 new_keyboard_input_event(Key::A, KeyEventType::Released),
831 new_keyboard_input_event(Key::C, KeyEventType::Released),
832 ]
833 );
834 }
835
836 #[fuchsia::test]
837 async fn display_ownership_initialized_with_inspect_node() {
838 let (test_event, handler_event) = EventPair::create();
839 let (loop_done_sender, _) = mpsc::unbounded::<()>();
840 let inspector = fuchsia_inspect::Inspector::default();
841 let fake_handlers_node = inspector.root().create_child("input_handlers_node");
842 let _ = DisplayWrangler::new(test_event);
844 let _handler = DisplayOwnership::new_internal(
845 handler_event,
846 Some(loop_done_sender),
847 &fake_handlers_node,
848 metrics::MetricsLogger::default(),
849 );
850 diagnostics_assertions::assert_data_tree!(inspector, root: {
851 input_handlers_node: {
852 display_ownership: {
853 events_received_count: 0u64,
854 events_handled_count: 0u64,
855 last_received_timestamp_ns: 0u64,
856 "fuchsia.inspect.Health": {
857 status: "STARTING_UP",
858 start_timestamp_nanos: diagnostics_assertions::AnyProperty
861 },
862 }
863 }
864 });
865 }
866
867 #[fuchsia::test]
868 async fn display_ownership_inspect_counts_events() {
869 let (test_event, handler_event) = EventPair::create();
870 let (test_sender, handler_receiver) = mpsc::unbounded::<InputEvent>();
871 let (handler_sender, _test_receiver) = mpsc::unbounded::<Vec<InputEvent>>();
872 let (loop_done_sender, mut loop_done) = mpsc::unbounded::<()>();
873 let mut wrangler = DisplayWrangler::new(test_event);
874 let inspector = fuchsia_inspect::Inspector::default();
875 let fake_handlers_node = inspector.root().create_child("input_handlers_node");
876 let handler = DisplayOwnership::new_internal(
877 handler_event,
878 Some(loop_done_sender),
879 &fake_handlers_node,
880 metrics::MetricsLogger::default(),
881 );
882 let handler_clone = handler.clone();
883 let handler_sender_clone = handler_sender.clone();
884 let _task = fasync::Task::local(async move {
885 handler_clone.handle_ownership_change(handler_sender_clone).await.unwrap();
886 });
887
888 let handler_clone_2 = handler.clone();
889 let _input_task = fasync::Task::local(async move {
890 let mut receiver = handler_receiver;
891 while let Some(event) = receiver.next().await {
892 let unhandled_event = UnhandledInputEvent::try_from(event).unwrap();
893 let out_events =
894 handler_clone_2.clone().handle_unhandled_input_event(unhandled_event).await;
895 handler_sender.unbounded_send(out_events).unwrap();
896 }
897 });
898
899 wrangler.set_owned();
901 loop_done.next().await;
902 test_sender
903 .unbounded_send(new_keyboard_input_event(Key::A, KeyEventType::Pressed))
904 .unwrap();
905 loop_done.next().await;
906
907 wrangler.set_unowned();
910 loop_done.next().await;
911 test_sender
912 .unbounded_send(new_keyboard_input_event(Key::B, KeyEventType::Pressed))
913 .unwrap();
914 loop_done.next().await;
915
916 wrangler.set_owned();
918 loop_done.next().await;
919
920 test_sender
922 .unbounded_send(new_keyboard_input_event(Key::A, KeyEventType::Released))
923 .unwrap();
924 loop_done.next().await;
925
926 diagnostics_assertions::assert_data_tree!(inspector, root: {
927 input_handlers_node: {
928 display_ownership: {
929 events_received_count: 3u64,
930 events_handled_count: 1u64,
931 last_received_timestamp_ns: 42u64,
932 "fuchsia.inspect.Health": {
933 status: "STARTING_UP",
934 start_timestamp_nanos: diagnostics_assertions::AnyProperty
937 },
938 }
939 }
940 });
941 }
942
943 #[fuchsia::test]
944 async fn display_ownership_peer_closed() {
945 let (test_event, handler_event) = EventPair::create();
946 let (loop_done_sender, mut loop_done) = mpsc::unbounded::<()>();
947
948 let mut wrangler = DisplayWrangler::new(test_event);
949 let handler = DisplayOwnership::new_for_test(
950 handler_event,
951 loop_done_sender,
952 metrics::MetricsLogger::default(),
953 );
954
955 let (handler_sender, _test_receiver) = mpsc::unbounded::<Vec<InputEvent>>();
956 let handler_clone = handler.clone();
957 let _task = fasync::Task::local(async move {
958 handler_clone.handle_ownership_change(handler_sender).await.unwrap();
959 });
960
961 wrangler.set_owned();
963 loop_done.next().await;
964
965 assert!(!handler.is_display_ownership_lost());
967
968 std::mem::drop(wrangler);
970
971 assert!(handler.is_display_ownership_lost());
973 }
974
975 #[fuchsia::test]
976 async fn orthogonal_input_client_owned_transitions() {
977 let (test_event, handler_event) = EventPair::create();
978 let (test_sender, handler_receiver) = mpsc::unbounded::<InputEvent>();
979 let (handler_sender, test_receiver) = mpsc::unbounded::<Vec<InputEvent>>();
980 let (loop_done_sender, mut loop_done) = mpsc::unbounded::<()>();
981
982 let mut wrangler = DisplayWrangler::new(test_event);
983 let handler = DisplayOwnership::new_for_test(
984 handler_event,
985 loop_done_sender,
986 metrics::MetricsLogger::default(),
987 );
988
989 let handler_clone = handler.clone();
990 let handler_sender_clone = handler_sender.clone();
991 let _task = fasync::Task::local(async move {
992 handler_clone.handle_ownership_change(handler_sender_clone).await.unwrap();
993 });
994
995 let handler_clone_2 = handler.clone();
996 let _input_task = fasync::Task::local(async move {
997 let mut receiver = handler_receiver;
998 while let Some(event) = receiver.next().await {
999 let unhandled_event = UnhandledInputEvent::try_from(event).unwrap();
1000 let out_events =
1001 handler_clone_2.clone().handle_unhandled_input_event(unhandled_event).await;
1002 handler_sender.unbounded_send(out_events).unwrap();
1003 }
1004 });
1005
1006 let fake_time = MonotonicInstant::from_nanos(42);
1007
1008 wrangler.set_owned();
1010 loop_done.next().await;
1011 assert!(!handler.is_display_ownership_lost());
1012 test_sender.unbounded_send(create_fake_input_event(fake_time)).unwrap();
1013 loop_done.next().await;
1014
1015 wrangler.set_client_input_owned();
1017 loop_done.next().await;
1018 assert!(handler.is_display_ownership_lost());
1019 test_sender.unbounded_send(create_fake_input_event(fake_time)).unwrap();
1020 loop_done.next().await;
1021
1022 wrangler.set_platform_input_owned();
1024 loop_done.next().await;
1025 assert!(!handler.is_display_ownership_lost());
1026 test_sender.unbounded_send(create_fake_input_event(fake_time)).unwrap();
1027 loop_done.next().await;
1028
1029 let actual: Vec<InputEvent> = test_receiver
1030 .take(3)
1031 .flat_map(|events| futures::stream::iter(events))
1032 .map(|e| e.into_with_event_time(fake_time))
1033 .collect()
1034 .await;
1035
1036 assert_eq!(
1037 actual,
1038 vec![
1039 create_fake_input_event(fake_time),
1040 create_fake_input_event(fake_time).into_handled(),
1041 create_fake_input_event(fake_time),
1042 ]
1043 );
1044 }
1045
1046 #[fuchsia::test]
1047 async fn orthogonal_virtcon_while_client_owned() {
1048 let (test_event, handler_event) = EventPair::create();
1049 let (loop_done_sender, mut loop_done) = mpsc::unbounded::<()>();
1050
1051 let mut wrangler = DisplayWrangler::new(test_event);
1052 let handler = DisplayOwnership::new_for_test(
1053 handler_event,
1054 loop_done_sender,
1055 metrics::MetricsLogger::default(),
1056 );
1057
1058 let (handler_sender, _test_receiver) = mpsc::unbounded::<Vec<InputEvent>>();
1059 let handler_clone = handler.clone();
1060 let _task = fasync::Task::local(async move {
1061 handler_clone.handle_ownership_change(handler_sender).await.unwrap();
1062 });
1063
1064 wrangler.set_owned();
1066 loop_done.next().await;
1067 assert!(!handler.is_display_ownership_lost());
1068
1069 wrangler.set_client_input_owned();
1071 loop_done.next().await;
1072 assert!(handler.is_display_ownership_lost());
1073
1074 wrangler.set_unowned();
1077 assert!(handler.is_display_ownership_lost());
1078
1079 wrangler.set_owned();
1082 assert!(handler.is_display_ownership_lost());
1083
1084 wrangler.set_platform_input_owned();
1087 loop_done.next().await;
1088 assert!(!handler.is_display_ownership_lost());
1089 }
1090
1091 #[fuchsia::test]
1092 async fn ownership_change_callback_invoked() {
1093 let (test_event, handler_event) = EventPair::create();
1094 let (loop_done_sender, mut loop_done) = mpsc::unbounded::<()>();
1095
1096 let mut wrangler = DisplayWrangler::new(test_event);
1097 let handler = DisplayOwnership::new_for_test(
1098 handler_event,
1099 loop_done_sender,
1100 metrics::MetricsLogger::default(),
1101 );
1102
1103 let (cb_sender, mut cb_receiver) = mpsc::unbounded::<bool>();
1104 handler.set_ownership_change_callback(move |owned| {
1105 let cb_sender = cb_sender.clone();
1106 Box::pin(async move {
1107 cb_sender.unbounded_send(owned).unwrap();
1108 })
1109 });
1110
1111 let (handler_sender, _test_receiver) = mpsc::unbounded::<Vec<InputEvent>>();
1112 let handler_clone = handler.clone();
1113 let _task = fasync::Task::local(async move {
1114 handler_clone.handle_ownership_change(handler_sender).await.unwrap();
1115 });
1116
1117 wrangler.set_owned();
1119 loop_done.next().await;
1120 assert_eq!(cb_receiver.next().await, Some(true));
1121
1122 wrangler.set_unowned();
1124 loop_done.next().await;
1125 assert_eq!(cb_receiver.next().await, Some(false));
1126
1127 wrangler.set_owned();
1129 loop_done.next().await;
1130 assert_eq!(cb_receiver.next().await, Some(true));
1131
1132 wrangler.set_client_input_owned();
1134 loop_done.next().await;
1135 assert_eq!(cb_receiver.next().await, Some(false));
1136
1137 wrangler.set_platform_input_owned();
1139 loop_done.next().await;
1140 assert_eq!(cb_receiver.next().await, Some(true));
1141 }
1142
1143 #[fuchsia::test]
1144 async fn peer_closed_terminates_without_busy_loop() {
1145 let (test_event, handler_event) = EventPair::create();
1146 test_event.signal_peer(Signals::empty(), *DISPLAY_UNOWNED | *INPUT_PLATFORM_OWNED).unwrap();
1148
1149 let ownership = Ownership::from(*DISPLAY_UNOWNED | *INPUT_PLATFORM_OWNED);
1150 assert!(ownership.is_display_ownership_lost());
1151
1152 drop(test_event);
1154
1155 let result = ownership.wait_ownership_change(&handler_event).await;
1157 assert_eq!(result, Err(Status::PEER_CLOSED));
1158 }
1159
1160 #[fuchsia::test]
1161 async fn peer_closed_transitions_to_unowned_then_terminates() {
1162 let (test_event, handler_event) = EventPair::create();
1163 test_event
1165 .signal_peer(Signals::empty(), *DISPLAY_PLATFORM_OWNED | *INPUT_PLATFORM_OWNED)
1166 .unwrap();
1167
1168 let ownership = Ownership::from(*DISPLAY_PLATFORM_OWNED | *INPUT_PLATFORM_OWNED);
1169 assert!(!ownership.is_display_ownership_lost());
1170
1171 drop(test_event);
1173
1174 let result = ownership.wait_ownership_change(&handler_event).await;
1176 assert!(result.is_ok());
1177 let cur_signals = result.unwrap();
1178 let unowned_ownership = Ownership::from(cur_signals);
1179 assert!(unowned_ownership.is_display_ownership_lost());
1180
1181 let result2 = unowned_ownership.wait_ownership_change(&handler_event).await;
1183 assert_eq!(result2, Err(Status::PEER_CLOSED));
1184 }
1185
1186 #[fuchsia::test]
1187 async fn contradictory_display_signals_terminates_with_bad_state() {
1188 let (test_event, handler_event) = EventPair::create();
1189 let signals = *DISPLAY_PLATFORM_OWNED | *DISPLAY_UNOWNED | *INPUT_PLATFORM_OWNED;
1192 test_event.signal_peer(Signals::empty(), signals).unwrap();
1193
1194 let ownership = Ownership::from(signals);
1195 assert!(ownership.is_display_ownership_lost());
1196
1197 let result = ownership.wait_ownership_change(&handler_event).await;
1198 assert_eq!(result, Err(Status::BAD_STATE));
1199 }
1200
1201 #[fuchsia::test]
1202 async fn contradictory_input_signals_terminates_with_bad_state() {
1203 let (test_event, handler_event) = EventPair::create();
1204 let signals = *DISPLAY_PLATFORM_OWNED | *INPUT_PLATFORM_OWNED | *INPUT_CLIENT_OWNED;
1207 test_event.signal_peer(Signals::empty(), signals).unwrap();
1208
1209 let ownership = Ownership::from(signals);
1210 assert!(ownership.is_display_ownership_lost());
1211
1212 let result = ownership.wait_ownership_change(&handler_event).await;
1213 assert_eq!(result, Err(Status::BAD_STATE));
1214 }
1215}