fuchsia_audio_dai/
discover.rs1use anyhow::Error;
6use fidl_fuchsia_io as fio;
7use std::path::Path;
8
9use crate::DigitalAudioInterface;
10
11const DAI_DEVICE_DIR: &str = "/dev/class/dai";
12
13pub async fn find_devices() -> Result<Vec<DigitalAudioInterface>, Error> {
15 let directory_proxy =
17 fuchsia_fs::directory::open_in_namespace(DAI_DEVICE_DIR, fio::Flags::empty())?;
18 find_devices_internal(directory_proxy).await
19}
20
21async fn find_devices_internal(
22 directory_proxy: fio::DirectoryProxy,
23) -> Result<Vec<DigitalAudioInterface>, Error> {
24 let files = fuchsia_fs::directory::readdir(&directory_proxy).await?;
25
26 let paths: Vec<_> =
27 files.iter().map(|file| Path::new(DAI_DEVICE_DIR).join(&file.name)).collect();
28 let devices = paths.iter().map(|path| DigitalAudioInterface::new(&path)).collect();
29
30 Ok(devices)
31}
32
33#[cfg(test)]
34mod tests {
35 use fuchsia_component_test::{
36 Capability, ChildOptions, LocalComponentHandles, RealmBuilder, Route,
37 };
38 use futures::channel::mpsc;
39 use futures::{SinkExt, StreamExt};
40 use realmbuilder_mock_helpers::mock_dev;
41
42 use super::*;
43 use crate::test::mock_dai_dev_with_io_devices;
44
45 #[fuchsia::test]
46 async fn test_env_dir_is_not_found() {
47 let _ = find_devices().await.expect_err("find devices okay");
48 }
49
50 async fn mock_client(
51 handles: LocalComponentHandles,
52 mut sender: mpsc::Sender<()>,
53 ) -> Result<(), Error> {
54 let proxy = handles.clone_from_namespace("dev/class/dai")?;
55 let devices = find_devices_internal(proxy).await.expect("should find devices");
56 assert_eq!(devices.len(), 2);
57 let _ = sender.send(()).await.unwrap();
58 Ok(())
59 }
60
61 #[fuchsia::test]
62 async fn devices_found_from_env() {
63 let (device_sender, mut device_receiver) = mpsc::channel(0);
64 let builder = RealmBuilder::new().await.expect("Failed to create test realm builder");
65
66 let mock_dev = builder
68 .add_local_child(
69 "mock-dev",
70 move |handles: LocalComponentHandles| {
71 Box::pin(mock_dev(
72 handles,
73 mock_dai_dev_with_io_devices("input1".to_string(), "output1".to_string()),
74 ))
75 },
76 ChildOptions::new().eager(),
77 )
78 .await
79 .expect("Failed adding mock /dev provider to topology");
80
81 let mock_client = builder
83 .add_local_child(
84 "mock-client",
85 move |handles: LocalComponentHandles| {
86 let s = device_sender.clone();
87 Box::pin(mock_client(handles, s.clone()))
88 },
89 ChildOptions::new().eager(),
90 )
91 .await
92 .expect("Failed adding mock client to topology");
93
94 builder
96 .add_route(
97 Route::new()
98 .capability(
99 Capability::directory("dev-dai")
100 .path(DAI_DEVICE_DIR)
101 .rights(fio::R_STAR_DIR),
102 )
103 .from(&mock_dev)
104 .to(&mock_client),
105 )
106 .await
107 .expect("Failed adding route for dai device directory");
108
109 let _test_topology = builder.build().await.unwrap();
110
111 let _ = device_receiver.next().await.expect("should receive devices");
112 }
113}