power_manager_integration_test_lib/mocks/
input_settings_service.rs1use fidl::endpoints::ServerEnd;
6use fidl_fuchsia_io::DirectoryMarker;
7use fuchsia_component::server::ServiceFs;
8use fuchsia_component_test::LocalComponentHandles;
9use futures::channel::mpsc;
10use futures::lock::Mutex;
11use futures::{StreamExt, TryStreamExt};
12use log::*;
13use std::sync::Arc;
14use {fidl_fuchsia_settings as fsettings, fuchsia_async as fasync};
15
16pub struct MockInputSettingsService {
18 settings_sender: Mutex<mpsc::Sender<fsettings::InputSettings>>,
21
22 settings_receiver: Mutex<mpsc::Receiver<fsettings::InputSettings>>,
26}
27
28impl MockInputSettingsService {
29 pub fn new() -> Arc<MockInputSettingsService> {
30 let (settings_sender, settings_receiver) = mpsc::channel(1);
31 Arc::new(Self {
32 settings_sender: Mutex::new(settings_sender),
33 settings_receiver: Mutex::new(settings_receiver),
34 })
35 }
36
37 pub async fn run(self: Arc<Self>, handles: LocalComponentHandles) -> Result<(), anyhow::Error> {
56 self.run_inner(handles.outgoing_dir).await
57 }
58
59 async fn run_inner(
60 self: Arc<Self>,
61 outgoing_dir: ServerEnd<DirectoryMarker>,
62 ) -> Result<(), anyhow::Error> {
63 let mut fs = ServiceFs::new();
64 fs.dir("svc").add_fidl_service(move |mut stream: fsettings::InputRequestStream| {
65 let this = self.clone();
66
67 let mut initial_settings_update = Some(generate_device_settings(false));
69
70 fasync::Task::local(async move {
71 info!("MockInputSettingsService: new connection");
72 while let Some(fsettings::InputRequest::Watch { responder }) =
73 stream.try_next().await.unwrap()
74 {
75 info!("MockInputSettingsService: received Watch request");
76 let settings = if let Some(settings) = initial_settings_update.take() {
77 settings
78 } else {
79 this.settings_receiver.lock().await.next().await.unwrap()
80 };
81
82 info!("MockInputSettingsService: sending input settings: {:?}", settings);
83 let _ = responder.send(&settings);
84 }
85
86 info!("MockInputSettingsService: closing connection")
87 })
88 .detach();
89 });
90
91 fs.serve_connection(outgoing_dir).unwrap();
92 fs.collect::<()>().await;
93
94 Ok(())
95 }
96
97 pub async fn set_mic_enabled(&self, mic_enabled: bool) {
98 info!("MockInputSettingsService: set mic enabled: {:?}", mic_enabled);
99 let input_settings = generate_device_settings(mic_enabled);
100 self.settings_sender.lock().await.try_send(input_settings).expect("try_send() failed");
101 }
102}
103
104fn generate_device_settings(mic_enabled: bool) -> fsettings::InputSettings {
105 fsettings::InputSettings {
106 devices: Some(vec![fsettings::InputDevice {
107 device_type: Some(fsettings::DeviceType::Microphone),
108 state: Some(fsettings::DeviceState {
109 toggle_flags: Some(if mic_enabled {
110 fsettings::ToggleStateFlags::AVAILABLE
111 } else {
112 fsettings::ToggleStateFlags::MUTED
113 }),
114 ..Default::default()
115 }),
116 ..Default::default()
117 }]),
118 ..Default::default()
119 }
120}
121
122#[cfg(test)]
123mod tests {
124 use super::*;
125 use fuchsia_component::client::connect_to_protocol_at_dir_svc;
126
127 fn parse_is_mic_enabled(settings: fsettings::InputSettings) -> bool {
129 let mic_settings = settings
130 .devices
131 .unwrap()
132 .into_iter()
133 .filter(|device| device.device_type == Some(fsettings::DeviceType::Microphone))
134 .collect::<Vec<_>>();
135
136 assert_eq!(mic_settings.len(), 1);
137
138 let is_enabled = mic_settings[0]
139 .state
140 .as_ref()
141 .unwrap()
142 .toggle_flags
143 .unwrap()
144 .contains(fsettings::ToggleStateFlags::AVAILABLE);
145
146 is_enabled
147 }
148
149 #[fuchsia::test]
150 async fn test_set_mic_enabled() {
151 let (dir, outgoing_dir) = fidl::endpoints::create_proxy::<DirectoryMarker>();
153 let mock = MockInputSettingsService::new();
154 let _task = fasync::Task::local(mock.clone().run_inner(outgoing_dir));
155
156 let settings_client =
158 connect_to_protocol_at_dir_svc::<fsettings::InputMarker>(&dir).unwrap();
159
160 let settings = settings_client.watch().await.unwrap();
162 assert_eq!(parse_is_mic_enabled(settings), false);
163
164 mock.set_mic_enabled(true).await;
166 let settings = settings_client.watch().await.unwrap();
167 assert_eq!(parse_is_mic_enabled(settings), true);
168 }
169}