Skip to main content

settings_test_common/fakes/
input_device_registry_service.rs

1// Copyright 2019 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use 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                    // Save the listener.
76                    listeners_handle.write().push(proxy.clone());
77                    // Acknowledge the registration.
78                    responder.send().expect("failed to ack RegisterListener call");
79                    // Send the last event if there was one.
80                    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}