blob: 8820c1ffc1c4cd64cd36bc3620fff99e098c32e0 [file] [log] [blame]
// Copyright 2021 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
use crate::interface_tests::Services;
use crate::interface_tests::ENV_NAME;
use crate::{input, utils};
use anyhow::{Context as _, Error};
use fidl_fuchsia_settings::{
DeviceState, DeviceStateSource, DeviceType, InputDevice, InputDeviceSettings, InputMarker,
InputRequest, InputSettings, Microphone, SourceState, ToggleStateFlags,
};
use fuchsia_async as fasync;
use fuchsia_component::server::ServiceFs;
use futures::prelude::*;
async fn validate_input(expected_mic_muted: Option<bool>) -> Result<(), Error> {
let env = create_service!(Services::Input,
InputRequest::Set { settings, responder } => {
if let Some(Microphone { muted, .. }) = settings.microphone {
assert_eq!(expected_mic_muted, muted);
responder.send(&mut (Ok(())))?;
}
},
InputRequest::Watch { responder } => {
responder.send(InputDeviceSettings {
microphone: Some(Microphone {
muted: expected_mic_muted,
..Microphone::EMPTY
}),
..InputDeviceSettings::EMPTY
})?;
}
);
let input_service =
env.connect_to_protocol::<InputMarker>().context("Failed to connect to input service")?;
let either = input::command(input_service, expected_mic_muted).await?;
if expected_mic_muted.is_none() {
if let utils::Either::Watch(mut stream) = either {
let output = stream.try_next().await?.expect("Watch should have a result");
assert_eq!(
output,
format!(
"{:#?}",
InputDeviceSettings {
microphone: Some(Microphone {
muted: expected_mic_muted,
..Microphone::EMPTY
}),
..InputDeviceSettings::EMPTY
}
)
);
} else {
panic!("Did not expect set result for a watch command");
}
} else if let utils::Either::Set(output) = either {
assert_eq!(
output,
format!("Successfully set mic mute to {}\n", expected_mic_muted.unwrap())
);
} else {
panic!("Did not expect watch result for a set command");
}
Ok(())
}
/// Creates a one-item list of input devices with the given properties.
fn create_input_devices(
device_type: DeviceType,
device_name: &str,
device_state: u64,
) -> Vec<InputDevice> {
let mut devices = Vec::new();
let mut source_states = Vec::new();
source_states.push(SourceState {
source: Some(DeviceStateSource::Hardware),
state: Some(DeviceState {
toggle_flags: ToggleStateFlags::from_bits(1),
..DeviceState::EMPTY
}),
..SourceState::EMPTY
});
source_states.push(SourceState {
source: Some(DeviceStateSource::Software),
state: Some(u64_to_state(device_state)),
..SourceState::EMPTY
});
let device = InputDevice {
device_name: Some(device_name.to_string()),
device_type: Some(device_type),
source_states: Some(source_states),
mutable_toggle_state: ToggleStateFlags::from_bits(12),
state: Some(u64_to_state(device_state)),
..InputDevice::EMPTY
};
devices.push(device);
devices
}
/// Transforms an u64 into an fuchsia_fidl_settings::DeviceState.
fn u64_to_state(num: u64) -> DeviceState {
DeviceState { toggle_flags: ToggleStateFlags::from_bits(num), ..DeviceState::EMPTY }
}
async fn validate_input2_watch() -> Result<(), Error> {
let env = create_service!(Services::Input,
InputRequest::Watch2 { responder } => {
responder.send(InputSettings {
devices: Some(
create_input_devices(
DeviceType::Camera,
"camera",
1,
)
),
..InputSettings::EMPTY
})?;
}
);
let input_service =
env.connect_to_protocol::<InputMarker>().context("Failed to connect to input service")?;
let output = assert_watch!(input::command2(input_service, None, None, None));
// Just check that the output contains some key strings that confirms the watch returned.
// The string representation may not necessarily be in the same order.
assert!(output.contains("Software"));
assert!(output.contains("source_states: Some"));
assert!(output.contains("toggle_flags: Some"));
assert!(output.contains("camera"));
assert!(output.contains("Available"));
Ok(())
}
async fn validate_input2_set(
device_type: DeviceType,
device_name: &'static str,
device_state: u64,
expected_state_string: &str,
) -> Result<(), Error> {
let env = create_service!(Services::Input,
InputRequest::SetStates { input_states, responder } => {
input_states.iter().for_each(move |state| {
assert_eq!(Some(device_type), state.device_type);
assert_eq!(Some(device_name.to_string()), state.name);
assert_eq!(Some(u64_to_state(device_state)), state.state);
});
responder.send(&mut (Ok(())))?;
}
);
let input_service =
env.connect_to_protocol::<InputMarker>().context("Failed to connect to input service")?;
let output = assert_set!(input::command2(
input_service,
Some(device_type),
Some(device_name.to_string()),
Some(u64_to_state(device_state)),
));
// Just check that the output contains some key strings that confirms the set returned.
// The string representation may not necessarily be in the same order.
assert!(output.contains(&format!("{:?}", device_type)));
assert!(output.contains(&format!("{:?}", device_name)));
assert!(output.contains(expected_state_string));
Ok(())
}
#[fuchsia_async::run_until_stalled(test)]
async fn test_input() -> Result<(), Error> {
println!("input service tests");
println!(" client calls input watch");
validate_input(None).await?;
println!(" client calls set input");
validate_input(Some(false)).await?;
println!("input2 service tests");
println!(" client calls input watch2");
validate_input2_watch().await?;
println!(" client calls set input with microphone");
validate_input2_set(DeviceType::Microphone, "microphone", 3, "Available | Active").await?;
println!(" client calls set input with camera");
validate_input2_set(DeviceType::Camera, "camera", 3, "Available | Active").await?;
Ok(())
}