1use crate::input_device_configuration::InputConfiguration;
6use anyhow::Error;
7use bitflags::bitflags;
8use fidl_fuchsia_settings::{
9 DeviceState as FidlDeviceState, DeviceStateSource as FidlDeviceStateSource,
10 DeviceType as FidlDeviceType, InputDevice as FidlInputDevice,
11 InputSettings as FidlInputSettings, SourceState as FidlSourceState,
12 ToggleStateFlags as FidlToggleFlags,
13};
14use serde::{Deserialize, Serialize};
15use settings_common::inspect::event::Nameable;
16use settings_storage::device_storage::DeviceStorageConvertible;
17use std::borrow::Cow;
18use std::collections::{HashMap, HashSet};
19use std::fmt;
20
21use super::input_controller::InputError;
22
23impl From<&InputInfo> for FidlInputSettings {
24 fn from(info: &InputInfo) -> Self {
25 FidlInputSettings {
26 devices: Some(
27 info.input_device_state
28 .input_categories
29 .iter()
30 .flat_map(|(_, category)| {
31 category.devices.values().cloned().map(|device| device.into())
32 })
33 .collect(),
34 ),
35 ..Default::default()
36 }
37 }
38}
39
40#[derive(PartialEq, Debug, Clone)]
41pub struct InputInfo {
42 pub input_device_state: InputState,
43}
44
45impl Nameable for InputInfo {
46 const NAME: &str = "Input";
47}
48
49impl DeviceStorageConvertible for InputInfo {
50 type Storable = InputInfoSources;
51
52 fn get_storable(&self) -> Cow<'_, Self::Storable> {
53 Cow::Owned(InputInfoSources { input_device_state: self.input_device_state.clone() })
54 }
55}
56
57#[derive(PartialEq, Default, Debug, Clone, Serialize, Deserialize)]
58#[serde(deny_unknown_fields)]
59pub struct InputInfoSources {
60 pub input_device_state: InputState,
61}
62
63#[derive(PartialEq, Default, Debug, Clone, Copy, Serialize, Deserialize)]
64pub struct Microphone {
67 pub muted: bool,
68}
69
70#[derive(PartialEq, Debug, Default, Clone, Serialize, Deserialize)]
71pub struct InputState {
74 pub input_categories: HashMap<InputDeviceType, InputCategory>,
76}
77
78impl InputState {
79 pub(crate) fn new() -> Self {
80 Self::default()
81 }
82
83 pub(crate) fn insert_device(&mut self, input_device: InputDevice, source: DeviceStateSource) {
86 self.set_source_state(
87 input_device.device_type,
88 input_device.name,
89 source,
90 input_device.state,
91 );
92 }
93
94 pub(crate) fn set_source_state(
98 &mut self,
99 device_type: InputDeviceType,
100 device_name: String,
101 source: DeviceStateSource,
102 state: DeviceState,
103 ) {
104 let category = self.input_categories.entry(device_type).or_default();
106
107 let input_device = category
109 .devices
110 .entry(device_name.clone())
111 .or_insert_with(|| InputDevice::new(device_name, device_type));
112
113 let _ = input_device.source_states.insert(source, state);
115 input_device.compute_input_state();
116 }
117
118 pub(crate) fn get_source_state(
123 &self,
124 device_type: InputDeviceType,
125 device_name: String,
126 source: DeviceStateSource,
127 ) -> Result<DeviceState, Error> {
128 Ok(*self
129 .input_categories
130 .get(&device_type)
131 .ok_or_else(|| {
132 InputError::UnexpectedError("Failed to get input category by input type".into())
133 })?
134 .devices
135 .get(&device_name)
136 .ok_or_else(|| {
137 InputError::UnexpectedError("Failed to get input device by device name".into())
138 })?
139 .source_states
140 .get(&source)
141 .ok_or_else(|| {
142 InputError::UnexpectedError("Failed to get state from source states".into())
143 })?)
144 }
145
146 #[cfg(test)]
151 pub(crate) fn get_state(
152 &self,
153 device_type: InputDeviceType,
154 device_name: String,
155 ) -> Result<DeviceState, Error> {
156 Ok(self
157 .input_categories
158 .get(&device_type)
159 .ok_or_else(|| {
160 InputError::UnexpectedError("Failed to get input category by input type".into())
161 })?
162 .devices
163 .get(&device_name)
164 .ok_or_else(|| {
165 InputError::UnexpectedError("Failed to get input device by device name".into())
166 })?
167 .state)
168 }
169
170 pub(crate) fn is_empty(&self) -> bool {
172 self.input_categories.is_empty()
173 }
174
175 pub(crate) fn device_types(&self) -> HashSet<InputDeviceType> {
178 self.input_categories.keys().cloned().collect()
179 }
180}
181
182impl From<InputConfiguration> for InputState {
183 fn from(config: InputConfiguration) -> Self {
184 let mut categories = HashMap::<InputDeviceType, InputCategory>::new();
185 let devices = config.devices;
186
187 devices.iter().for_each(|device_config| {
188 let input_device_type = device_config.device_type;
190 let category = categories.entry(input_device_type).or_default();
191
192 let device_name = device_config.device_name.clone();
194 let device = category
195 .devices
196 .entry(device_name.clone())
197 .or_insert_with(|| InputDevice::new(device_name, input_device_type));
198
199 device_config.source_states.iter().for_each(|source_state| {
201 let value = DeviceState::from_bits(source_state.state).unwrap_or_default();
202 let _ = device.source_states.insert(source_state.source, value);
204 });
205
206 device.compute_input_state();
208 });
209 InputState { input_categories: categories }
210 }
211}
212
213#[derive(PartialEq, Debug, Default, Clone, Serialize, Deserialize)]
214pub struct InputCategory {
215 pub devices: HashMap<String, InputDevice>,
220}
221
222#[derive(PartialEq, Debug, Clone, Serialize, Deserialize)]
223pub struct InputDevice {
224 pub name: String,
226
227 pub device_type: InputDeviceType,
229
230 pub source_states: HashMap<DeviceStateSource, DeviceState>,
232
233 pub state: DeviceState,
235}
236
237impl InputDevice {
238 fn new(name: String, device_type: InputDeviceType) -> Self {
239 Self {
240 name,
241 device_type,
242 source_states: HashMap::<DeviceStateSource, DeviceState>::new(),
243 state: DeviceState::new(),
244 }
245 }
246
247 fn compute_input_state(&mut self) {
248 let mut computed_state = DeviceState::from_bits(0).unwrap();
249
250 for state in self.source_states.values() {
251 if state.has_error() {
252 computed_state |= DeviceState::ERROR;
253 }
254 if state.has_state(DeviceState::DISABLED) {
255 computed_state |= DeviceState::DISABLED | DeviceState::MUTED;
256 }
257 if state.has_state(DeviceState::MUTED) {
258 computed_state |= DeviceState::MUTED;
259 }
260 if state.has_state(DeviceState::ACTIVE) {
261 computed_state |= DeviceState::ACTIVE | DeviceState::AVAILABLE;
262 }
263 }
264
265 if computed_state.has_error() {
269 self.state = DeviceState::ERROR;
270 } else if computed_state.has_state(DeviceState::DISABLED) {
271 self.state = DeviceState::DISABLED | DeviceState::MUTED;
272 } else if computed_state.has_state(DeviceState::MUTED) {
273 self.state = DeviceState::MUTED;
274 } else if computed_state.has_state(DeviceState::ACTIVE) {
275 self.state = DeviceState::ACTIVE | DeviceState::AVAILABLE;
276 } else {
277 self.state = DeviceState::AVAILABLE;
278 }
279 }
280}
281
282impl From<InputDevice> for FidlInputDevice {
283 fn from(device: InputDevice) -> Self {
284 let mut result = FidlInputDevice::default();
285
286 let source_states = Some(
288 device
289 .source_states
290 .keys()
291 .map(|source| FidlSourceState {
292 source: Some((*source).into()),
293 state: Some(
294 (*device.source_states.get(source).expect("Source state map key missing"))
295 .into(),
296 ),
297 ..Default::default()
298 })
299 .collect(),
300 );
301
302 let mutable_toggle_state: FidlDeviceState =
303 DeviceState::default_mutable_toggle_state().into();
304 result.device_name = Some(device.name.clone());
305 result.device_type = Some(device.device_type.into());
306 result.source_states = source_states;
307 result.mutable_toggle_state = mutable_toggle_state.toggle_flags;
308 result.state = Some(device.state.into());
309 result
310 }
311}
312
313#[derive(PartialEq, Eq, Debug, Copy, Clone, Hash, Serialize, Deserialize)]
314#[allow(clippy::upper_case_acronyms)]
315pub enum InputDeviceType {
316 CAMERA,
317 MICROPHONE,
318}
319
320impl fmt::Display for InputDeviceType {
328 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
329 match self {
330 InputDeviceType::CAMERA => fmt.write_str("camera"),
331 InputDeviceType::MICROPHONE => fmt.write_str("microphone"),
332 }
333 }
334}
335
336impl From<FidlDeviceType> for InputDeviceType {
337 fn from(device_type: FidlDeviceType) -> Self {
338 match device_type {
339 FidlDeviceType::Camera => InputDeviceType::CAMERA,
340 FidlDeviceType::Microphone => InputDeviceType::MICROPHONE,
341 }
342 }
343}
344
345impl From<InputDeviceType> for FidlDeviceType {
346 fn from(device_type: InputDeviceType) -> Self {
347 match device_type {
348 InputDeviceType::CAMERA => FidlDeviceType::Camera,
349 InputDeviceType::MICROPHONE => FidlDeviceType::Microphone,
350 }
351 }
352}
353
354#[derive(PartialEq, Eq, Debug, Copy, Clone, Hash, Serialize, Deserialize)]
355#[allow(clippy::upper_case_acronyms)]
356pub enum DeviceStateSource {
357 HARDWARE,
358 SOFTWARE,
359}
360
361impl From<FidlDeviceStateSource> for DeviceStateSource {
362 fn from(device_state_source: FidlDeviceStateSource) -> Self {
363 match device_state_source {
364 FidlDeviceStateSource::Hardware => DeviceStateSource::HARDWARE,
365 FidlDeviceStateSource::Software => DeviceStateSource::SOFTWARE,
366 }
367 }
368}
369
370impl From<DeviceStateSource> for FidlDeviceStateSource {
371 fn from(device_state_source: DeviceStateSource) -> Self {
372 match device_state_source {
373 DeviceStateSource::HARDWARE => FidlDeviceStateSource::Hardware,
374 DeviceStateSource::SOFTWARE => FidlDeviceStateSource::Software,
375 }
376 }
377}
378
379bitflags! {
380 #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
381 pub struct DeviceState : u64 {
382 const AVAILABLE = 0b00000001;
383 const ACTIVE = 0b00000010;
384 const MUTED = 0b00000100;
385 const DISABLED = 0b00001000;
386 const ERROR = 0b00010000;
387 }
388}
389
390impl Default for DeviceState {
391 fn default() -> Self {
392 Self::new()
393 }
394}
395
396impl DeviceState {
397 pub(crate) fn new() -> Self {
398 Self::AVAILABLE
400 }
401
402 fn default_mutable_toggle_state() -> Self {
404 DeviceState::MUTED | DeviceState::DISABLED
405 }
406
407 pub(crate) fn has_state(&self, state: DeviceState) -> bool {
411 *self & state == state
412 }
413
414 fn has_error(&self) -> bool {
416 let is_err = *self & DeviceState::ERROR == DeviceState::ERROR;
417 let incompatible_state = self.has_state(DeviceState::ACTIVE | DeviceState::DISABLED)
418 || self.has_state(DeviceState::ACTIVE | DeviceState::MUTED)
419 || self.has_state(DeviceState::AVAILABLE | DeviceState::DISABLED)
420 || self.has_state(DeviceState::AVAILABLE | DeviceState::MUTED);
421 is_err || incompatible_state
422 }
423}
424
425impl From<FidlDeviceState> for DeviceState {
426 fn from(device_state: FidlDeviceState) -> Self {
427 if let Some(toggle_flags) = device_state.toggle_flags {
428 if let Some(res) = Self::from_bits(toggle_flags.bits()) {
429 return res;
430 }
431 }
432 Self::default_mutable_toggle_state()
433 }
434}
435
436impl From<DeviceState> for FidlDeviceState {
437 fn from(device_state: DeviceState) -> Self {
438 FidlDeviceState {
439 toggle_flags: FidlToggleFlags::from_bits(device_state.bits()),
440 ..Default::default()
441 }
442 }
443}
444
445bitflags_serde_legacy::impl_traits!(DeviceState);
446
447#[cfg(test)]
448mod tests {
449 use super::*;
450 use crate::input_device_configuration::{InputDeviceConfiguration, SourceState};
451
452 const DEFAULT_MIC_NAME: &str = "microphone";
453 const DEFAULT_CAMERA_NAME: &str = "camera";
454 const AVAILABLE_BITS: u64 = 1;
455 const MUTED_BITS: u64 = 4;
456 const MUTED_DISABLED_BITS: u64 = 12;
457
458 fn create_fidl_input_device(
460 device_name: &str,
461 device_type: FidlDeviceType,
462 sw_bits: u64,
463 hw_bits: u64,
464 overall_bits: u64,
465 ) -> FidlInputDevice {
466 FidlInputDevice {
467 device_name: Some(device_name.to_string()),
468 device_type: Some(device_type),
469 source_states: Some(vec![
470 FidlSourceState {
471 source: Some(FidlDeviceStateSource::Hardware),
472 state: Some(FidlDeviceState {
473 toggle_flags: FidlToggleFlags::from_bits(hw_bits),
474 ..Default::default()
475 }),
476 ..Default::default()
477 },
478 FidlSourceState {
479 source: Some(FidlDeviceStateSource::Software),
480 state: Some(FidlDeviceState {
481 toggle_flags: FidlToggleFlags::from_bits(sw_bits),
482 ..Default::default()
483 }),
484 ..Default::default()
485 },
486 ]),
487 mutable_toggle_state: FidlToggleFlags::from_bits(MUTED_DISABLED_BITS),
488 state: Some(FidlDeviceState {
489 toggle_flags: FidlToggleFlags::from_bits(overall_bits),
490 ..Default::default()
491 }),
492 ..Default::default()
493 }
494 }
495
496 fn create_input_device(
498 device_name: &str,
499 device_type: InputDeviceType,
500 sw_bits: u64,
501 hw_bits: u64,
502 overall_bits: u64,
503 ) -> InputDevice {
504 let mut input_device = InputDevice::new(device_name.to_string(), device_type);
505 let _ = input_device
506 .source_states
507 .insert(DeviceStateSource::SOFTWARE, DeviceState::from_bits(sw_bits).unwrap());
508 let _ = input_device
509 .source_states
510 .insert(DeviceStateSource::HARDWARE, DeviceState::from_bits(hw_bits).unwrap());
511 input_device.state = DeviceState::from_bits(overall_bits).unwrap();
512 input_device
513 }
514
515 fn create_device_config(
517 device_name: &str,
518 device_type: InputDeviceType,
519 sw_state: u64,
520 hw_state: u64,
521 ) -> InputDeviceConfiguration {
522 InputDeviceConfiguration {
523 device_name: device_name.to_string(),
524 device_type,
525 source_states: vec![
526 SourceState { source: DeviceStateSource::SOFTWARE, state: sw_state },
527 SourceState { source: DeviceStateSource::HARDWARE, state: hw_state },
528 ],
529 mutable_toggle_state: MUTED_DISABLED_BITS,
530 }
531 }
532
533 fn verify_fidl_input_device_eq(res: FidlInputDevice, expected: FidlInputDevice) {
536 assert_eq!(res.device_name, expected.device_name);
537 assert_eq!(res.device_type, expected.device_type);
538 assert_eq!(res.mutable_toggle_state, expected.mutable_toggle_state);
539 assert_eq!(res.state, expected.state);
540 let res_source_states = res.source_states.unwrap();
541 for source_state in expected.source_states.unwrap() {
542 assert!(&res_source_states.contains(&source_state));
543 }
544 }
545
546 #[fuchsia::test]
547 fn test_input_state_manipulation() {
548 let mut input_state = InputState::new();
549
550 input_state.set_source_state(
552 InputDeviceType::MICROPHONE,
553 DEFAULT_MIC_NAME.to_string(),
554 DeviceStateSource::SOFTWARE,
555 DeviceState::from_bits(AVAILABLE_BITS).unwrap(),
556 );
557 input_state.set_source_state(
558 InputDeviceType::MICROPHONE,
559 DEFAULT_MIC_NAME.to_string(),
560 DeviceStateSource::HARDWARE,
561 DeviceState::from_bits(MUTED_BITS).unwrap(),
562 );
563 input_state.set_source_state(
564 InputDeviceType::CAMERA,
565 DEFAULT_CAMERA_NAME.to_string(),
566 DeviceStateSource::SOFTWARE,
567 DeviceState::from_bits(MUTED_BITS).unwrap(),
568 );
569 input_state.set_source_state(
570 InputDeviceType::CAMERA,
571 DEFAULT_CAMERA_NAME.to_string(),
572 DeviceStateSource::HARDWARE,
573 DeviceState::from_bits(AVAILABLE_BITS).unwrap(),
574 );
575
576 assert_eq!(
578 input_state
579 .get_source_state(
580 InputDeviceType::MICROPHONE,
581 DEFAULT_MIC_NAME.to_string(),
582 DeviceStateSource::SOFTWARE
583 )
584 .unwrap(),
585 DeviceState::from_bits(AVAILABLE_BITS).unwrap(),
586 );
587 assert_eq!(
588 input_state
589 .get_source_state(
590 InputDeviceType::MICROPHONE,
591 DEFAULT_MIC_NAME.to_string(),
592 DeviceStateSource::HARDWARE
593 )
594 .unwrap(),
595 DeviceState::from_bits(MUTED_BITS).unwrap(),
596 );
597 assert_eq!(
598 input_state
599 .get_source_state(
600 InputDeviceType::CAMERA,
601 DEFAULT_CAMERA_NAME.to_string(),
602 DeviceStateSource::SOFTWARE
603 )
604 .unwrap(),
605 DeviceState::from_bits(MUTED_BITS).unwrap(),
606 );
607 assert_eq!(
608 input_state
609 .get_source_state(
610 InputDeviceType::CAMERA,
611 DEFAULT_CAMERA_NAME.to_string(),
612 DeviceStateSource::HARDWARE
613 )
614 .unwrap(),
615 DeviceState::from_bits(AVAILABLE_BITS).unwrap(),
616 );
617
618 assert_eq!(
620 input_state
621 .get_state(InputDeviceType::MICROPHONE, DEFAULT_MIC_NAME.to_string())
622 .unwrap(),
623 DeviceState::from_bits(MUTED_BITS).unwrap(),
624 );
625 assert_eq!(
626 input_state
627 .get_state(InputDeviceType::CAMERA, DEFAULT_CAMERA_NAME.to_string())
628 .unwrap(),
629 DeviceState::from_bits(MUTED_BITS).unwrap(),
630 );
631
632 input_state.set_source_state(
634 InputDeviceType::MICROPHONE,
635 DEFAULT_MIC_NAME.to_string(),
636 DeviceStateSource::HARDWARE,
637 DeviceState::from_bits(AVAILABLE_BITS).unwrap(),
638 );
639 assert_eq!(
640 input_state
641 .get_state(InputDeviceType::MICROPHONE, DEFAULT_MIC_NAME.to_string())
642 .unwrap(),
643 DeviceState::from_bits(AVAILABLE_BITS).unwrap(),
644 );
645
646 input_state.set_source_state(
648 InputDeviceType::CAMERA,
649 DEFAULT_CAMERA_NAME.to_string(),
650 DeviceStateSource::SOFTWARE,
651 DeviceState::from_bits(AVAILABLE_BITS).unwrap(),
652 );
653 assert_eq!(
654 input_state
655 .get_state(InputDeviceType::CAMERA, DEFAULT_CAMERA_NAME.to_string())
656 .unwrap(),
657 DeviceState::from_bits(AVAILABLE_BITS).unwrap(),
658 );
659 }
660
661 #[fuchsia::test]
662 fn test_input_configuration_to_input_state() {
663 let config = InputConfiguration {
664 devices: vec![
665 create_device_config(
666 DEFAULT_MIC_NAME,
667 InputDeviceType::MICROPHONE,
668 MUTED_BITS,
669 AVAILABLE_BITS,
670 ),
671 create_device_config(
672 DEFAULT_CAMERA_NAME,
673 InputDeviceType::CAMERA,
674 AVAILABLE_BITS,
675 AVAILABLE_BITS,
676 ),
677 create_device_config(
678 "camera2",
679 InputDeviceType::CAMERA,
680 AVAILABLE_BITS,
681 MUTED_DISABLED_BITS,
682 ),
683 ],
684 };
685 let result: InputState = config.into();
686 assert_eq!(
687 result
688 .get_source_state(
689 InputDeviceType::MICROPHONE,
690 DEFAULT_MIC_NAME.to_string(),
691 DeviceStateSource::SOFTWARE,
692 )
693 .unwrap(),
694 DeviceState::from_bits(MUTED_BITS).unwrap(),
695 );
696 assert_eq!(
697 result
698 .get_source_state(
699 InputDeviceType::MICROPHONE,
700 DEFAULT_MIC_NAME.to_string(),
701 DeviceStateSource::HARDWARE,
702 )
703 .unwrap(),
704 DeviceState::from_bits(AVAILABLE_BITS).unwrap(),
705 );
706 assert_eq!(
707 result
708 .get_source_state(
709 InputDeviceType::CAMERA,
710 DEFAULT_CAMERA_NAME.to_string(),
711 DeviceStateSource::SOFTWARE,
712 )
713 .unwrap(),
714 DeviceState::from_bits(AVAILABLE_BITS).unwrap(),
715 );
716 assert_eq!(
717 result
718 .get_source_state(
719 InputDeviceType::CAMERA,
720 DEFAULT_CAMERA_NAME.to_string(),
721 DeviceStateSource::HARDWARE,
722 )
723 .unwrap(),
724 DeviceState::from_bits(AVAILABLE_BITS).unwrap(),
725 );
726 assert_eq!(
727 result
728 .get_source_state(
729 InputDeviceType::CAMERA,
730 "camera2".to_string(),
731 DeviceStateSource::SOFTWARE,
732 )
733 .unwrap(),
734 DeviceState::from_bits(AVAILABLE_BITS).unwrap(),
735 );
736 assert_eq!(
737 result
738 .get_source_state(
739 InputDeviceType::CAMERA,
740 "camera2".to_string(),
741 DeviceStateSource::HARDWARE,
742 )
743 .unwrap(),
744 DeviceState::from_bits(MUTED_DISABLED_BITS).unwrap(),
745 );
746 }
747
748 #[fuchsia::test]
749 fn test_overall_state() {
752 let mut mic_available = create_input_device(
755 DEFAULT_MIC_NAME,
756 InputDeviceType::MICROPHONE,
757 AVAILABLE_BITS,
758 AVAILABLE_BITS,
759 AVAILABLE_BITS,
760 );
761 let mut mic_disabled = create_input_device(
762 DEFAULT_MIC_NAME,
763 InputDeviceType::MICROPHONE,
764 MUTED_DISABLED_BITS,
765 AVAILABLE_BITS,
766 MUTED_DISABLED_BITS,
767 );
768 let mut mic_muted = create_input_device(
769 DEFAULT_MIC_NAME,
770 InputDeviceType::MICROPHONE,
771 AVAILABLE_BITS,
772 MUTED_BITS,
773 MUTED_BITS,
774 );
775 let mut mic_active = create_input_device(
776 DEFAULT_MIC_NAME,
777 InputDeviceType::MICROPHONE,
778 3,
779 AVAILABLE_BITS,
780 3,
781 );
782 let mut mic_error = create_input_device(
783 DEFAULT_MIC_NAME,
784 InputDeviceType::MICROPHONE,
785 10,
786 AVAILABLE_BITS,
787 16,
788 );
789
790 mic_available.compute_input_state();
791 mic_disabled.compute_input_state();
792 mic_muted.compute_input_state();
793 mic_active.compute_input_state();
794 mic_error.compute_input_state();
795
796 assert_eq!(mic_available.state, DeviceState::AVAILABLE);
797 assert_eq!(mic_disabled.state, DeviceState::DISABLED | DeviceState::MUTED);
798 assert_eq!(mic_muted.state, DeviceState::MUTED);
799 assert_eq!(mic_active.state, DeviceState::ACTIVE | DeviceState::AVAILABLE);
800 assert_eq!(mic_error.state, DeviceState::ERROR);
801 }
802
803 #[fuchsia::test]
804 fn test_input_device_to_fidl_input_device() {
805 let expected_mic: FidlInputDevice = create_fidl_input_device(
806 DEFAULT_MIC_NAME,
807 FidlDeviceType::Microphone,
808 AVAILABLE_BITS,
809 AVAILABLE_BITS,
810 AVAILABLE_BITS,
811 );
812 let expected_cam: FidlInputDevice = create_fidl_input_device(
813 DEFAULT_CAMERA_NAME,
814 FidlDeviceType::Camera,
815 AVAILABLE_BITS,
816 MUTED_BITS,
817 MUTED_BITS,
818 );
819
820 let mut mic = InputDevice::new(DEFAULT_MIC_NAME.to_string(), InputDeviceType::MICROPHONE);
821 let _ = mic
822 .source_states
823 .insert(DeviceStateSource::SOFTWARE, DeviceState::from_bits(AVAILABLE_BITS).unwrap());
824 let _ = mic
825 .source_states
826 .insert(DeviceStateSource::HARDWARE, DeviceState::from_bits(AVAILABLE_BITS).unwrap());
827 mic.state = DeviceState::from_bits(AVAILABLE_BITS).unwrap();
828
829 let mut cam = InputDevice::new(DEFAULT_CAMERA_NAME.to_string(), InputDeviceType::CAMERA);
830 let _ = cam
831 .source_states
832 .insert(DeviceStateSource::SOFTWARE, DeviceState::from_bits(AVAILABLE_BITS).unwrap());
833 let _ = cam
834 .source_states
835 .insert(DeviceStateSource::HARDWARE, DeviceState::from_bits(MUTED_BITS).unwrap());
836 cam.state = DeviceState::from_bits(MUTED_BITS).unwrap();
837
838 let mic_res: FidlInputDevice = mic.into();
839 let cam_res: FidlInputDevice = cam.into();
840
841 verify_fidl_input_device_eq(mic_res, expected_mic);
842 verify_fidl_input_device_eq(cam_res, expected_cam);
843 }
844
845 #[fuchsia::test]
846 fn test_input_device_type_to_string() {
847 assert_eq!(InputDeviceType::CAMERA.to_string(), DEFAULT_CAMERA_NAME);
848 assert_eq!(InputDeviceType::MICROPHONE.to_string(), DEFAULT_MIC_NAME);
849 }
850
851 #[fuchsia::test]
852 fn test_fidl_device_type_to_device_type() {
853 let cam_res: FidlDeviceType = InputDeviceType::CAMERA.into();
854 let mic_res: FidlDeviceType = InputDeviceType::MICROPHONE.into();
855 assert_eq!(cam_res, FidlDeviceType::Camera);
856 assert_eq!(mic_res, FidlDeviceType::Microphone);
857 }
858
859 #[fuchsia::test]
860 fn test_device_type_to_fidl_device_type() {
861 let cam_res: InputDeviceType = FidlDeviceType::Camera.into();
862 let mic_res: InputDeviceType = FidlDeviceType::Microphone.into();
863 assert_eq!(cam_res, InputDeviceType::CAMERA);
864 assert_eq!(mic_res, InputDeviceType::MICROPHONE);
865 }
866
867 #[fuchsia::test]
868 fn test_fidl_device_state_source_to_device_state_source() {
869 let hw_res: FidlDeviceStateSource = DeviceStateSource::HARDWARE.into();
870 let sw_res: FidlDeviceStateSource = DeviceStateSource::SOFTWARE.into();
871 assert_eq!(hw_res, FidlDeviceStateSource::Hardware);
872 assert_eq!(sw_res, FidlDeviceStateSource::Software);
873 }
874
875 #[fuchsia::test]
876 fn test_device_state_source_to_fidl_device_state_source() {
877 let hw_res: DeviceStateSource = FidlDeviceStateSource::Hardware.into();
878 let sw_res: DeviceStateSource = FidlDeviceStateSource::Software.into();
879 assert_eq!(hw_res, DeviceStateSource::HARDWARE);
880 assert_eq!(sw_res, DeviceStateSource::SOFTWARE);
881 }
882
883 #[fuchsia::test]
884 fn test_device_state_errors() {
885 let available_disabled = DeviceState::from_bits(9).unwrap();
886 let available_muted = DeviceState::from_bits(5).unwrap();
887 let active_muted = DeviceState::from_bits(6).unwrap();
888 let active_disabled = DeviceState::from_bits(10).unwrap();
889 assert!(available_disabled.has_error());
890 assert!(available_muted.has_error());
891 assert!(active_muted.has_error());
892 assert!(active_disabled.has_error());
893 }
894
895 #[fuchsia::test]
896 fn test_fidl_device_state_to_device_state() {
897 let device_state: DeviceState = FidlDeviceState {
898 toggle_flags: FidlToggleFlags::from_bits(MUTED_BITS),
899 ..Default::default()
900 }
901 .into();
902 assert_eq!(device_state, DeviceState::from_bits(MUTED_BITS).unwrap(),);
903 }
904
905 #[fuchsia::test]
906 fn test_device_state_to_fidl_device_state() {
907 let fidl_device_state: FidlDeviceState = DeviceState::from_bits(MUTED_BITS).unwrap().into();
908 assert_eq!(
909 fidl_device_state,
910 FidlDeviceState {
911 toggle_flags: FidlToggleFlags::from_bits(MUTED_BITS),
912 ..Default::default()
913 }
914 );
915 }
916}