use crate::base::SettingInfo;
use crate::handler::setting_handler::ControllerError;
use crate::input::input_device_configuration::InputConfiguration;
use settings_storage::device_storage::DeviceStorageConvertible;
use anyhow::Error;
use bitflags::bitflags;
use fidl_fuchsia_settings::{
DeviceState as FidlDeviceState, DeviceStateSource as FidlDeviceStateSource,
DeviceType as FidlDeviceType, InputDevice as FidlInputDevice,
InputSettings as FidlInputSettings, SourceState as FidlSourceState,
ToggleStateFlags as FidlToggleFlags,
};
use serde::{Deserialize, Serialize};
use std::borrow::Cow;
use std::collections::{HashMap, HashSet};
use std::fmt;
impl From<SettingInfo> for FidlInputSettings {
fn from(response: SettingInfo) -> Self {
if let SettingInfo::Input(info) = response {
let mut input_settings = FidlInputSettings::default();
let mut input_devices: Vec<FidlInputDevice> = Vec::new();
info.input_device_state.input_categories.iter().for_each(|(_, category)| {
category.devices.iter().for_each(|(_, device)| {
input_devices.push(device.clone().into());
})
});
input_settings.devices = Some(input_devices);
input_settings
} else {
panic!("Incorrect value sent to input");
}
}
}
#[derive(PartialEq, Debug, Clone)]
pub struct InputInfo {
pub input_device_state: InputState,
}
impl DeviceStorageConvertible for InputInfo {
type Storable = InputInfoSources;
fn get_storable(&self) -> Cow<'_, Self::Storable> {
Cow::Owned(InputInfoSources { input_device_state: self.input_device_state.clone() })
}
}
#[derive(PartialEq, Default, Debug, Clone, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct InputInfoSources {
pub input_device_state: InputState,
}
#[derive(PartialEq, Default, Debug, Clone, Copy, Serialize, Deserialize)]
pub struct Microphone {
pub muted: bool,
}
#[derive(PartialEq, Debug, Default, Clone, Serialize, Deserialize)]
pub struct InputState {
pub input_categories: HashMap<InputDeviceType, InputCategory>,
}
impl InputState {
pub(crate) fn new() -> Self {
Self::default()
}
pub(crate) fn insert_device(&mut self, input_device: InputDevice, source: DeviceStateSource) {
self.set_source_state(
input_device.device_type,
input_device.name,
source,
input_device.state,
);
}
pub(crate) fn set_source_state(
&mut self,
device_type: InputDeviceType,
device_name: String,
source: DeviceStateSource,
state: DeviceState,
) {
let category = self.input_categories.entry(device_type).or_default();
let input_device = category
.devices
.entry(device_name.clone())
.or_insert_with(|| InputDevice::new(device_name, device_type));
let _ = input_device.source_states.insert(source, state);
input_device.compute_input_state();
}
pub(crate) fn get_source_state(
&self,
device_type: InputDeviceType,
device_name: String,
source: DeviceStateSource,
) -> Result<DeviceState, Error> {
Ok(*self
.input_categories
.get(&device_type)
.ok_or_else(|| {
ControllerError::UnexpectedError(
"Failed to get input category by input type".into(),
)
})?
.devices
.get(&device_name)
.ok_or_else(|| {
ControllerError::UnexpectedError("Failed to get input device by device name".into())
})?
.source_states
.get(&source)
.ok_or_else(|| {
ControllerError::UnexpectedError("Failed to get state from source states".into())
})?)
}
#[cfg(test)]
pub(crate) fn get_state(
&self,
device_type: InputDeviceType,
device_name: String,
) -> Result<DeviceState, Error> {
Ok(self
.input_categories
.get(&device_type)
.ok_or_else(|| {
ControllerError::UnexpectedError(
"Failed to get input category by input type".into(),
)
})?
.devices
.get(&device_name)
.ok_or_else(|| {
ControllerError::UnexpectedError("Failed to get input device by device name".into())
})?
.state)
}
pub(crate) fn is_empty(&self) -> bool {
self.input_categories.is_empty()
}
pub(crate) fn device_types(&self) -> HashSet<InputDeviceType> {
self.input_categories.keys().cloned().collect()
}
}
impl From<InputConfiguration> for InputState {
fn from(config: InputConfiguration) -> Self {
let mut categories = HashMap::<InputDeviceType, InputCategory>::new();
let devices = config.devices;
devices.iter().for_each(|device_config| {
let input_device_type = device_config.device_type;
let category = categories.entry(input_device_type).or_default();
let device_name = device_config.device_name.clone();
let device = category
.devices
.entry(device_name.clone())
.or_insert_with(|| InputDevice::new(device_name, input_device_type));
device_config.source_states.iter().for_each(|source_state| {
let value = DeviceState::from_bits(source_state.state).unwrap_or_default();
let _ = device.source_states.insert(source_state.source, value);
});
device.compute_input_state();
});
InputState { input_categories: categories }
}
}
#[derive(PartialEq, Debug, Default, Clone, Serialize, Deserialize)]
pub struct InputCategory {
pub devices: HashMap<String, InputDevice>,
}
#[derive(PartialEq, Debug, Clone, Serialize, Deserialize)]
pub struct InputDevice {
pub name: String,
pub device_type: InputDeviceType,
pub source_states: HashMap<DeviceStateSource, DeviceState>,
pub state: DeviceState,
}
impl InputDevice {
fn new(name: String, device_type: InputDeviceType) -> Self {
Self {
name,
device_type,
source_states: HashMap::<DeviceStateSource, DeviceState>::new(),
state: DeviceState::new(),
}
}
fn compute_input_state(&mut self) {
let mut computed_state = DeviceState::from_bits(0).unwrap();
for state in self.source_states.values() {
if state.has_error() {
computed_state |= DeviceState::ERROR;
}
if state.has_state(DeviceState::DISABLED) {
computed_state |= DeviceState::DISABLED | DeviceState::MUTED;
}
if state.has_state(DeviceState::MUTED) {
computed_state |= DeviceState::MUTED;
}
if state.has_state(DeviceState::ACTIVE) {
computed_state |= DeviceState::ACTIVE | DeviceState::AVAILABLE;
}
}
if computed_state.has_error() {
self.state = DeviceState::ERROR;
} else if computed_state.has_state(DeviceState::DISABLED) {
self.state = DeviceState::DISABLED | DeviceState::MUTED;
} else if computed_state.has_state(DeviceState::MUTED) {
self.state = DeviceState::MUTED;
} else if computed_state.has_state(DeviceState::ACTIVE) {
self.state = DeviceState::ACTIVE | DeviceState::AVAILABLE;
} else {
self.state = DeviceState::AVAILABLE;
}
}
}
impl From<InputDevice> for FidlInputDevice {
fn from(device: InputDevice) -> Self {
let mut result = FidlInputDevice::default();
let source_states = Some(
device
.source_states
.keys()
.map(|source| FidlSourceState {
source: Some((*source).into()),
state: Some(
(*device.source_states.get(source).expect("Source state map key missing"))
.into(),
),
..Default::default()
})
.collect(),
);
let mutable_toggle_state: FidlDeviceState =
DeviceState::default_mutable_toggle_state().into();
result.device_name = Some(device.name.clone());
result.device_type = Some(device.device_type.into());
result.source_states = source_states;
result.mutable_toggle_state = mutable_toggle_state.toggle_flags;
result.state = Some(device.state.into());
result
}
}
#[derive(PartialEq, Eq, Debug, Copy, Clone, Hash, Serialize, Deserialize)]
#[allow(clippy::upper_case_acronyms)]
pub enum InputDeviceType {
CAMERA,
MICROPHONE,
}
impl fmt::Display for InputDeviceType {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
InputDeviceType::CAMERA => fmt.write_str("camera"),
InputDeviceType::MICROPHONE => fmt.write_str("microphone"),
}
}
}
impl From<FidlDeviceType> for InputDeviceType {
fn from(device_type: FidlDeviceType) -> Self {
match device_type {
FidlDeviceType::Camera => InputDeviceType::CAMERA,
FidlDeviceType::Microphone => InputDeviceType::MICROPHONE,
}
}
}
impl From<InputDeviceType> for FidlDeviceType {
fn from(device_type: InputDeviceType) -> Self {
match device_type {
InputDeviceType::CAMERA => FidlDeviceType::Camera,
InputDeviceType::MICROPHONE => FidlDeviceType::Microphone,
}
}
}
#[derive(PartialEq, Eq, Debug, Copy, Clone, Hash, Serialize, Deserialize)]
#[allow(clippy::upper_case_acronyms)]
pub enum DeviceStateSource {
HARDWARE,
SOFTWARE,
}
impl From<FidlDeviceStateSource> for DeviceStateSource {
fn from(device_state_source: FidlDeviceStateSource) -> Self {
match device_state_source {
FidlDeviceStateSource::Hardware => DeviceStateSource::HARDWARE,
FidlDeviceStateSource::Software => DeviceStateSource::SOFTWARE,
}
}
}
impl From<DeviceStateSource> for FidlDeviceStateSource {
fn from(device_state_source: DeviceStateSource) -> Self {
match device_state_source {
DeviceStateSource::HARDWARE => FidlDeviceStateSource::Hardware,
DeviceStateSource::SOFTWARE => FidlDeviceStateSource::Software,
}
}
}
bitflags! {
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct DeviceState : u64 {
const AVAILABLE = 0b00000001;
const ACTIVE = 0b00000010;
const MUTED = 0b00000100;
const DISABLED = 0b00001000;
const ERROR = 0b00010000;
}
}
impl Default for DeviceState {
fn default() -> Self {
Self::new()
}
}
impl DeviceState {
pub(crate) fn new() -> Self {
Self::AVAILABLE
}
fn default_mutable_toggle_state() -> Self {
DeviceState::MUTED | DeviceState::DISABLED
}
pub(crate) fn has_state(&self, state: DeviceState) -> bool {
*self & state == state
}
fn has_error(&self) -> bool {
let is_err = *self & DeviceState::ERROR == DeviceState::ERROR;
let incompatible_state = self.has_state(DeviceState::ACTIVE | DeviceState::DISABLED)
|| self.has_state(DeviceState::ACTIVE | DeviceState::MUTED)
|| self.has_state(DeviceState::AVAILABLE | DeviceState::DISABLED)
|| self.has_state(DeviceState::AVAILABLE | DeviceState::MUTED);
is_err || incompatible_state
}
}
impl From<FidlDeviceState> for DeviceState {
fn from(device_state: FidlDeviceState) -> Self {
if let Some(toggle_flags) = device_state.toggle_flags {
if let Some(res) = Self::from_bits(toggle_flags.bits()) {
return res;
}
}
Self::default_mutable_toggle_state()
}
}
impl From<DeviceState> for FidlDeviceState {
fn from(device_state: DeviceState) -> Self {
FidlDeviceState {
toggle_flags: FidlToggleFlags::from_bits(device_state.bits()),
..Default::default()
}
}
}
bitflags_serde_legacy::impl_traits!(DeviceState);
#[cfg(test)]
mod tests {
use super::*;
use crate::input::input_device_configuration::{InputDeviceConfiguration, SourceState};
const DEFAULT_MIC_NAME: &str = "microphone";
const DEFAULT_CAMERA_NAME: &str = "camera";
const AVAILABLE_BITS: u64 = 1;
const MUTED_BITS: u64 = 4;
const MUTED_DISABLED_BITS: u64 = 12;
fn create_fidl_input_device(
device_name: &str,
device_type: FidlDeviceType,
sw_bits: u64,
hw_bits: u64,
overall_bits: u64,
) -> FidlInputDevice {
FidlInputDevice {
device_name: Some(device_name.to_string()),
device_type: Some(device_type),
source_states: Some(vec![
FidlSourceState {
source: Some(FidlDeviceStateSource::Hardware),
state: Some(FidlDeviceState {
toggle_flags: FidlToggleFlags::from_bits(hw_bits),
..Default::default()
}),
..Default::default()
},
FidlSourceState {
source: Some(FidlDeviceStateSource::Software),
state: Some(FidlDeviceState {
toggle_flags: FidlToggleFlags::from_bits(sw_bits),
..Default::default()
}),
..Default::default()
},
]),
mutable_toggle_state: FidlToggleFlags::from_bits(MUTED_DISABLED_BITS),
state: Some(FidlDeviceState {
toggle_flags: FidlToggleFlags::from_bits(overall_bits),
..Default::default()
}),
..Default::default()
}
}
fn create_input_device(
device_name: &str,
device_type: InputDeviceType,
sw_bits: u64,
hw_bits: u64,
overall_bits: u64,
) -> InputDevice {
let mut input_device = InputDevice::new(device_name.to_string(), device_type);
let _ = input_device
.source_states
.insert(DeviceStateSource::SOFTWARE, DeviceState::from_bits(sw_bits).unwrap());
let _ = input_device
.source_states
.insert(DeviceStateSource::HARDWARE, DeviceState::from_bits(hw_bits).unwrap());
input_device.state = DeviceState::from_bits(overall_bits).unwrap();
input_device
}
fn create_device_config(
device_name: &str,
device_type: InputDeviceType,
sw_state: u64,
hw_state: u64,
) -> InputDeviceConfiguration {
InputDeviceConfiguration {
device_name: device_name.to_string(),
device_type,
source_states: vec![
SourceState { source: DeviceStateSource::SOFTWARE, state: sw_state },
SourceState { source: DeviceStateSource::HARDWARE, state: hw_state },
],
mutable_toggle_state: MUTED_DISABLED_BITS,
}
}
fn verify_fidl_input_device_eq(res: FidlInputDevice, expected: FidlInputDevice) {
assert_eq!(res.device_name, expected.device_name);
assert_eq!(res.device_type, expected.device_type);
assert_eq!(res.mutable_toggle_state, expected.mutable_toggle_state);
assert_eq!(res.state, expected.state);
let res_source_states = res.source_states.unwrap();
for source_state in expected.source_states.unwrap() {
assert!(&res_source_states.contains(&source_state));
}
}
#[fuchsia::test]
fn test_input_state_manipulation() {
let mut input_state = InputState::new();
input_state.set_source_state(
InputDeviceType::MICROPHONE,
DEFAULT_MIC_NAME.to_string(),
DeviceStateSource::SOFTWARE,
DeviceState::from_bits(AVAILABLE_BITS).unwrap(),
);
input_state.set_source_state(
InputDeviceType::MICROPHONE,
DEFAULT_MIC_NAME.to_string(),
DeviceStateSource::HARDWARE,
DeviceState::from_bits(MUTED_BITS).unwrap(),
);
input_state.set_source_state(
InputDeviceType::CAMERA,
DEFAULT_CAMERA_NAME.to_string(),
DeviceStateSource::SOFTWARE,
DeviceState::from_bits(MUTED_BITS).unwrap(),
);
input_state.set_source_state(
InputDeviceType::CAMERA,
DEFAULT_CAMERA_NAME.to_string(),
DeviceStateSource::HARDWARE,
DeviceState::from_bits(AVAILABLE_BITS).unwrap(),
);
assert_eq!(
input_state
.get_source_state(
InputDeviceType::MICROPHONE,
DEFAULT_MIC_NAME.to_string(),
DeviceStateSource::SOFTWARE
)
.unwrap(),
DeviceState::from_bits(AVAILABLE_BITS).unwrap(),
);
assert_eq!(
input_state
.get_source_state(
InputDeviceType::MICROPHONE,
DEFAULT_MIC_NAME.to_string(),
DeviceStateSource::HARDWARE
)
.unwrap(),
DeviceState::from_bits(MUTED_BITS).unwrap(),
);
assert_eq!(
input_state
.get_source_state(
InputDeviceType::CAMERA,
DEFAULT_CAMERA_NAME.to_string(),
DeviceStateSource::SOFTWARE
)
.unwrap(),
DeviceState::from_bits(MUTED_BITS).unwrap(),
);
assert_eq!(
input_state
.get_source_state(
InputDeviceType::CAMERA,
DEFAULT_CAMERA_NAME.to_string(),
DeviceStateSource::HARDWARE
)
.unwrap(),
DeviceState::from_bits(AVAILABLE_BITS).unwrap(),
);
assert_eq!(
input_state
.get_state(InputDeviceType::MICROPHONE, DEFAULT_MIC_NAME.to_string())
.unwrap(),
DeviceState::from_bits(MUTED_BITS).unwrap(),
);
assert_eq!(
input_state
.get_state(InputDeviceType::CAMERA, DEFAULT_CAMERA_NAME.to_string())
.unwrap(),
DeviceState::from_bits(MUTED_BITS).unwrap(),
);
input_state.set_source_state(
InputDeviceType::MICROPHONE,
DEFAULT_MIC_NAME.to_string(),
DeviceStateSource::HARDWARE,
DeviceState::from_bits(AVAILABLE_BITS).unwrap(),
);
assert_eq!(
input_state
.get_state(InputDeviceType::MICROPHONE, DEFAULT_MIC_NAME.to_string())
.unwrap(),
DeviceState::from_bits(AVAILABLE_BITS).unwrap(),
);
input_state.set_source_state(
InputDeviceType::CAMERA,
DEFAULT_CAMERA_NAME.to_string(),
DeviceStateSource::SOFTWARE,
DeviceState::from_bits(AVAILABLE_BITS).unwrap(),
);
assert_eq!(
input_state
.get_state(InputDeviceType::CAMERA, DEFAULT_CAMERA_NAME.to_string())
.unwrap(),
DeviceState::from_bits(AVAILABLE_BITS).unwrap(),
);
}
#[fuchsia::test]
fn test_input_configuration_to_input_state() {
let config = InputConfiguration {
devices: vec![
create_device_config(
DEFAULT_MIC_NAME,
InputDeviceType::MICROPHONE,
MUTED_BITS,
AVAILABLE_BITS,
),
create_device_config(
DEFAULT_CAMERA_NAME,
InputDeviceType::CAMERA,
AVAILABLE_BITS,
AVAILABLE_BITS,
),
create_device_config(
"camera2",
InputDeviceType::CAMERA,
AVAILABLE_BITS,
MUTED_DISABLED_BITS,
),
],
};
let result: InputState = config.into();
assert_eq!(
result
.get_source_state(
InputDeviceType::MICROPHONE,
DEFAULT_MIC_NAME.to_string(),
DeviceStateSource::SOFTWARE,
)
.unwrap(),
DeviceState::from_bits(MUTED_BITS).unwrap(),
);
assert_eq!(
result
.get_source_state(
InputDeviceType::MICROPHONE,
DEFAULT_MIC_NAME.to_string(),
DeviceStateSource::HARDWARE,
)
.unwrap(),
DeviceState::from_bits(AVAILABLE_BITS).unwrap(),
);
assert_eq!(
result
.get_source_state(
InputDeviceType::CAMERA,
DEFAULT_CAMERA_NAME.to_string(),
DeviceStateSource::SOFTWARE,
)
.unwrap(),
DeviceState::from_bits(AVAILABLE_BITS).unwrap(),
);
assert_eq!(
result
.get_source_state(
InputDeviceType::CAMERA,
DEFAULT_CAMERA_NAME.to_string(),
DeviceStateSource::HARDWARE,
)
.unwrap(),
DeviceState::from_bits(AVAILABLE_BITS).unwrap(),
);
assert_eq!(
result
.get_source_state(
InputDeviceType::CAMERA,
"camera2".to_string(),
DeviceStateSource::SOFTWARE,
)
.unwrap(),
DeviceState::from_bits(AVAILABLE_BITS).unwrap(),
);
assert_eq!(
result
.get_source_state(
InputDeviceType::CAMERA,
"camera2".to_string(),
DeviceStateSource::HARDWARE,
)
.unwrap(),
DeviceState::from_bits(MUTED_DISABLED_BITS).unwrap(),
);
}
#[fuchsia::test]
fn test_overall_state() {
let mut mic_available = create_input_device(
DEFAULT_MIC_NAME,
InputDeviceType::MICROPHONE,
AVAILABLE_BITS,
AVAILABLE_BITS,
AVAILABLE_BITS,
);
let mut mic_disabled = create_input_device(
DEFAULT_MIC_NAME,
InputDeviceType::MICROPHONE,
MUTED_DISABLED_BITS,
AVAILABLE_BITS,
MUTED_DISABLED_BITS,
);
let mut mic_muted = create_input_device(
DEFAULT_MIC_NAME,
InputDeviceType::MICROPHONE,
AVAILABLE_BITS,
MUTED_BITS,
MUTED_BITS,
);
let mut mic_active = create_input_device(
DEFAULT_MIC_NAME,
InputDeviceType::MICROPHONE,
3,
AVAILABLE_BITS,
3,
);
let mut mic_error = create_input_device(
DEFAULT_MIC_NAME,
InputDeviceType::MICROPHONE,
10,
AVAILABLE_BITS,
16,
);
mic_available.compute_input_state();
mic_disabled.compute_input_state();
mic_muted.compute_input_state();
mic_active.compute_input_state();
mic_error.compute_input_state();
assert_eq!(mic_available.state, DeviceState::AVAILABLE);
assert_eq!(mic_disabled.state, DeviceState::DISABLED | DeviceState::MUTED);
assert_eq!(mic_muted.state, DeviceState::MUTED);
assert_eq!(mic_active.state, DeviceState::ACTIVE | DeviceState::AVAILABLE);
assert_eq!(mic_error.state, DeviceState::ERROR);
}
#[fuchsia::test]
fn test_input_device_to_fidl_input_device() {
let expected_mic: FidlInputDevice = create_fidl_input_device(
DEFAULT_MIC_NAME,
FidlDeviceType::Microphone,
AVAILABLE_BITS,
AVAILABLE_BITS,
AVAILABLE_BITS,
);
let expected_cam: FidlInputDevice = create_fidl_input_device(
DEFAULT_CAMERA_NAME,
FidlDeviceType::Camera,
AVAILABLE_BITS,
MUTED_BITS,
MUTED_BITS,
);
let mut mic = InputDevice::new(DEFAULT_MIC_NAME.to_string(), InputDeviceType::MICROPHONE);
let _ = mic
.source_states
.insert(DeviceStateSource::SOFTWARE, DeviceState::from_bits(AVAILABLE_BITS).unwrap());
let _ = mic
.source_states
.insert(DeviceStateSource::HARDWARE, DeviceState::from_bits(AVAILABLE_BITS).unwrap());
mic.state = DeviceState::from_bits(AVAILABLE_BITS).unwrap();
let mut cam = InputDevice::new(DEFAULT_CAMERA_NAME.to_string(), InputDeviceType::CAMERA);
let _ = cam
.source_states
.insert(DeviceStateSource::SOFTWARE, DeviceState::from_bits(AVAILABLE_BITS).unwrap());
let _ = cam
.source_states
.insert(DeviceStateSource::HARDWARE, DeviceState::from_bits(MUTED_BITS).unwrap());
cam.state = DeviceState::from_bits(MUTED_BITS).unwrap();
let mic_res: FidlInputDevice = mic.into();
let cam_res: FidlInputDevice = cam.into();
verify_fidl_input_device_eq(mic_res, expected_mic);
verify_fidl_input_device_eq(cam_res, expected_cam);
}
#[fuchsia::test]
fn test_input_device_type_to_string() {
assert_eq!(InputDeviceType::CAMERA.to_string(), DEFAULT_CAMERA_NAME);
assert_eq!(InputDeviceType::MICROPHONE.to_string(), DEFAULT_MIC_NAME);
}
#[fuchsia::test]
fn test_fidl_device_type_to_device_type() {
let cam_res: FidlDeviceType = InputDeviceType::CAMERA.into();
let mic_res: FidlDeviceType = InputDeviceType::MICROPHONE.into();
assert_eq!(cam_res, FidlDeviceType::Camera);
assert_eq!(mic_res, FidlDeviceType::Microphone);
}
#[fuchsia::test]
fn test_device_type_to_fidl_device_type() {
let cam_res: InputDeviceType = FidlDeviceType::Camera.into();
let mic_res: InputDeviceType = FidlDeviceType::Microphone.into();
assert_eq!(cam_res, InputDeviceType::CAMERA);
assert_eq!(mic_res, InputDeviceType::MICROPHONE);
}
#[fuchsia::test]
fn test_fidl_device_state_source_to_device_state_source() {
let hw_res: FidlDeviceStateSource = DeviceStateSource::HARDWARE.into();
let sw_res: FidlDeviceStateSource = DeviceStateSource::SOFTWARE.into();
assert_eq!(hw_res, FidlDeviceStateSource::Hardware);
assert_eq!(sw_res, FidlDeviceStateSource::Software);
}
#[fuchsia::test]
fn test_device_state_source_to_fidl_device_state_source() {
let hw_res: DeviceStateSource = FidlDeviceStateSource::Hardware.into();
let sw_res: DeviceStateSource = FidlDeviceStateSource::Software.into();
assert_eq!(hw_res, DeviceStateSource::HARDWARE);
assert_eq!(sw_res, DeviceStateSource::SOFTWARE);
}
#[fuchsia::test]
fn test_device_state_errors() {
let available_disabled = DeviceState::from_bits(9).unwrap();
let available_muted = DeviceState::from_bits(5).unwrap();
let active_muted = DeviceState::from_bits(6).unwrap();
let active_disabled = DeviceState::from_bits(10).unwrap();
assert!(available_disabled.has_error());
assert!(available_muted.has_error());
assert!(active_muted.has_error());
assert!(active_disabled.has_error());
}
#[fuchsia::test]
fn test_fidl_device_state_to_device_state() {
let device_state: DeviceState = FidlDeviceState {
toggle_flags: FidlToggleFlags::from_bits(MUTED_BITS),
..Default::default()
}
.into();
assert_eq!(device_state, DeviceState::from_bits(MUTED_BITS).unwrap(),);
}
#[fuchsia::test]
fn test_device_state_to_fidl_device_state() {
let fidl_device_state: FidlDeviceState = DeviceState::from_bits(MUTED_BITS).unwrap().into();
assert_eq!(
fidl_device_state,
FidlDeviceState {
toggle_flags: FidlToggleFlags::from_bits(MUTED_BITS),
..Default::default()
}
);
}
}