settings_test_common/fakes/
input_device_registry_service.rs1use crate::fakes::service::Service;
6use crate::helpers::clone_media_buttons_event_without_wake_lease;
7use anyhow::{Error, format_err};
8use fidl::endpoints::ServerEnd;
9use fidl::prelude::*;
10use fidl_fuchsia_ui_input::MediaButtonsEvent;
11use fidl_fuchsia_ui_policy::MediaButtonsListenerProxy;
12use fuchsia_async as fasync;
13use fuchsia_sync::RwLock;
14use futures::TryStreamExt;
15use std::rc::Rc;
16
17pub struct InputDeviceRegistryService {
18 listeners: Rc<RwLock<Vec<MediaButtonsListenerProxy>>>,
19 last_sent_event: Rc<RwLock<Option<MediaButtonsEvent>>>,
20 fail: bool,
21}
22
23#[allow(clippy::new_without_default)]
24impl InputDeviceRegistryService {
25 pub fn new() -> Self {
26 Self {
27 listeners: Rc::new(RwLock::new(Vec::new())),
28 last_sent_event: Rc::new(RwLock::new(None)),
29 fail: false,
30 }
31 }
32
33 pub fn set_fail(&mut self, fail: bool) {
34 self.fail = fail;
35 }
36
37 #[allow(clippy::await_holding_lock)]
38 pub async fn send_media_button_event(&self, event: MediaButtonsEvent) {
39 *self.last_sent_event.write() = Some(clone_media_buttons_event_without_wake_lease(&event));
40 for listener in self.listeners.read().iter() {
41 let _ = listener.on_event(clone_media_buttons_event_without_wake_lease(&event)).await;
42 }
43 }
44}
45
46impl Service for InputDeviceRegistryService {
47 fn can_handle_service(&self, service_name: &str) -> bool {
48 service_name == fidl_fuchsia_ui_policy::DeviceListenerRegistryMarker::PROTOCOL_NAME
49 }
50
51 fn process_stream(&mut self, service_name: &str, channel: zx::Channel) -> Result<(), Error> {
52 if !self.can_handle_service(service_name) {
53 return Err(format_err!("can't handle service"));
54 }
55
56 let mut manager_stream =
57 ServerEnd::<fidl_fuchsia_ui_policy::DeviceListenerRegistryMarker>::new(channel)
58 .into_stream();
59
60 let listeners_handle = self.listeners.clone();
61 let last_event = self.last_sent_event.clone();
62
63 if self.fail {
64 return Err(format_err!("exiting early"));
65 }
66
67 fasync::Task::local(async move {
68 while let Some(req) = manager_stream.try_next().await.unwrap() {
69 if let fidl_fuchsia_ui_policy::DeviceListenerRegistryRequest::RegisterListener {
70 listener,
71 responder,
72 } = req
73 {
74 let proxy = listener.into_proxy();
75 listeners_handle.write().push(proxy.clone());
77 responder.send().expect("failed to ack RegisterListener call");
79 let last_event_clone = last_event
81 .read()
82 .as_ref()
83 .map(clone_media_buttons_event_without_wake_lease);
84 if let Some(event) = last_event_clone {
85 let _ = proxy.on_event(event).await;
86 }
87 }
88 }
89 })
90 .detach();
91
92 Ok(())
93 }
94}