power_manager_integration_test_lib/mocks/
input_settings_service.rsuse fidl::endpoints::ServerEnd;
use fidl_fuchsia_io::DirectoryMarker;
use fuchsia_component::server::ServiceFs;
use fuchsia_component_test::LocalComponentHandles;
use futures::channel::mpsc;
use futures::lock::Mutex;
use futures::{StreamExt, TryStreamExt};
use std::sync::Arc;
use tracing::*;
use {fidl_fuchsia_settings as fsettings, fuchsia_async as fasync};
pub struct MockInputSettingsService {
settings_sender: Mutex<mpsc::Sender<fsettings::InputSettings>>,
settings_receiver: Mutex<mpsc::Receiver<fsettings::InputSettings>>,
}
impl MockInputSettingsService {
pub fn new() -> Arc<MockInputSettingsService> {
let (settings_sender, settings_receiver) = mpsc::channel(1);
Arc::new(Self {
settings_sender: Mutex::new(settings_sender),
settings_receiver: Mutex::new(settings_receiver),
})
}
pub async fn run(self: Arc<Self>, handles: LocalComponentHandles) -> Result<(), anyhow::Error> {
self.run_inner(handles.outgoing_dir).await
}
async fn run_inner(
self: Arc<Self>,
outgoing_dir: ServerEnd<DirectoryMarker>,
) -> Result<(), anyhow::Error> {
let mut fs = ServiceFs::new();
fs.dir("svc").add_fidl_service(move |mut stream: fsettings::InputRequestStream| {
let this = self.clone();
let mut initial_settings_update = Some(generate_device_settings(false));
fasync::Task::local(async move {
info!("MockInputSettingsService: new connection");
while let Some(fsettings::InputRequest::Watch { responder }) =
stream.try_next().await.unwrap()
{
info!("MockInputSettingsService: received Watch request");
let settings = if let Some(settings) = initial_settings_update.take() {
settings
} else {
this.settings_receiver.lock().await.next().await.unwrap()
};
info!("MockInputSettingsService: sending input settings: {:?}", settings);
let _ = responder.send(&settings);
}
info!("MockInputSettingsService: closing connection")
})
.detach();
});
fs.serve_connection(outgoing_dir).unwrap();
fs.collect::<()>().await;
Ok(())
}
pub async fn set_mic_enabled(&self, mic_enabled: bool) {
info!("MockInputSettingsService: set mic enabled: {:?}", mic_enabled);
let input_settings = generate_device_settings(mic_enabled);
self.settings_sender.lock().await.try_send(input_settings).expect("try_send() failed");
}
}
fn generate_device_settings(mic_enabled: bool) -> fsettings::InputSettings {
fsettings::InputSettings {
devices: Some(vec![fsettings::InputDevice {
device_type: Some(fsettings::DeviceType::Microphone),
state: Some(fsettings::DeviceState {
toggle_flags: Some(if mic_enabled {
fsettings::ToggleStateFlags::AVAILABLE
} else {
fsettings::ToggleStateFlags::MUTED
}),
..Default::default()
}),
..Default::default()
}]),
..Default::default()
}
}
#[cfg(test)]
mod tests {
use super::*;
use fuchsia_component::client::connect_to_protocol_at_dir_svc;
fn parse_is_mic_enabled(settings: fsettings::InputSettings) -> bool {
let mic_settings = settings
.devices
.unwrap()
.into_iter()
.filter(|device| device.device_type == Some(fsettings::DeviceType::Microphone))
.collect::<Vec<_>>();
assert_eq!(mic_settings.len(), 1);
let is_enabled = mic_settings[0]
.state
.as_ref()
.unwrap()
.toggle_flags
.unwrap()
.contains(fsettings::ToggleStateFlags::AVAILABLE);
is_enabled
}
#[fuchsia::test]
async fn test_set_mic_enabled() {
let (dir, outgoing_dir) = fidl::endpoints::create_proxy::<DirectoryMarker>();
let mock = MockInputSettingsService::new();
let _task = fasync::Task::local(mock.clone().run_inner(outgoing_dir));
let settings_client =
connect_to_protocol_at_dir_svc::<fsettings::InputMarker>(&dir).unwrap();
let settings = settings_client.watch().await.unwrap();
assert_eq!(parse_is_mic_enabled(settings), false);
mock.set_mic_enabled(true).await;
let settings = settings_client.watch().await.unwrap();
assert_eq!(parse_is_mic_enabled(settings), true);
}
}