1 // Copyright 2019 The Chromium OS Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 //! Provides an interface for playing and recording audio through CRAS server.
5 //!
6 //! `CrasClient` implements `StreamSource` trait and it can create playback or capture
7 //! stream - `CrasStream` which can be a
8 //! - `PlaybackBufferStream` for audio playback or
9 //! - `CaptureBufferStream` for audio capture.
10 //!
11 //! # Example of file audio playback
12 //!
13 //! `PlaybackBuffer`s to be filled with audio samples are obtained by calling
14 //! `next_playback_buffer` from `CrasStream`.
15 //!
16 //! Users playing audio fill the provided buffers with audio. When a `PlaybackBuffer` is dropped,
17 //! the samples written to it are committed to the `CrasStream` it came from.
18 //!
19 //!
20 //! ```
21 //! // An example of playing raw audio data from a given file
22 //! use std::env;
23 //! use std::fs::File;
24 //! use std::io::{Read, Write};
25 //! use std::thread::{spawn, JoinHandle};
26 //! type Result<T> = std::result::Result<T, BoxError>;
27 //!
28 //! use libcras::{BoxError, CrasClient, CrasClientType};
29 //! use audio_streams::{SampleFormat, StreamSource};
30 //!
31 //! const BUFFER_SIZE: usize = 256;
32 //! const FRAME_RATE: u32 = 44100;
33 //! const NUM_CHANNELS: usize = 2;
34 //! const FORMAT: SampleFormat = SampleFormat::S16LE;
35 //!
36 //! # fn main() -> Result<()> {
37 //! #    let args: Vec<String> = env::args().collect();
38 //! #    match args.len() {
39 //! #        2 => {
40 //!              let mut cras_client = CrasClient::new()?;
41 //!              cras_client.set_client_type(CrasClientType::CRAS_CLIENT_TYPE_TEST);
42 //!              let (_control, mut stream) = cras_client
43 //!                  .new_playback_stream(NUM_CHANNELS, FORMAT, FRAME_RATE, BUFFER_SIZE)?;
44 //!
45 //!              // Plays 1000 * BUFFER_SIZE samples from the given file
46 //!              let mut file = File::open(&args[1])?;
47 //!              let mut local_buffer = [0u8; BUFFER_SIZE * NUM_CHANNELS * 2];
48 //!              for _i in 0..1000 {
49 //!                  // Reads data to local buffer
50 //!                  let _read_count = file.read(&mut local_buffer)?;
51 //!
52 //!                  // Gets writable buffer from stream and
53 //!                  let mut buffer = stream.next_playback_buffer()?;
54 //!                  // Writes data to stream buffer
55 //!                  let _write_frames = buffer.write(&local_buffer)?;
56 //!              }
57 //!              // Stream and client should gracefully be closed out of this scope
58 //! #        }
59 //! #        _ => {
60 //! #            println!("{} /path/to/playback_file.raw", args[0]);
61 //! #        }
62 //! #    };
63 //! #    Ok(())
64 //! # }
65 //! ```
66 //!
67 //! # Example of file audio capture
68 //!
69 //! `CaptureBuffer`s which contain audio samples are obtained by calling
70 //! `next_capture_buffer` from `CrasStream`.
71 //!
72 //! Users get captured audio samples from the provided buffers. When a `CaptureBuffer` is dropped,
73 //! the number of read samples will be committed to the `CrasStream` it came from.
74 //! ```
75 //! use std::env;
76 //! use std::fs::File;
77 //! use std::io::{Read, Write};
78 //! use std::thread::{spawn, JoinHandle};
79 //! type Result<T> = std::result::Result<T, BoxError>;
80 //!
81 //! use libcras::{BoxError, CrasClient, CrasClientType};
82 //! use audio_streams::{SampleFormat, StreamSource};
83 //!
84 //! const BUFFER_SIZE: usize = 256;
85 //! const FRAME_RATE: u32 = 44100;
86 //! const NUM_CHANNELS: usize = 2;
87 //! const FORMAT: SampleFormat = SampleFormat::S16LE;
88 //!
89 //! # fn main() -> Result<()> {
90 //! #    let args: Vec<String> = env::args().collect();
91 //! #    match args.len() {
92 //! #        2 => {
93 //!              let mut cras_client = CrasClient::new()?;
94 //!              cras_client.set_client_type(CrasClientType::CRAS_CLIENT_TYPE_TEST);
95 //!              let (_control, mut stream) = cras_client
96 //!                  .new_capture_stream(NUM_CHANNELS, FORMAT, FRAME_RATE, BUFFER_SIZE)?;
97 //!
98 //!              // Capture 1000 * BUFFER_SIZE samples to the given file
99 //!              let mut file = File::create(&args[1])?;
100 //!              let mut local_buffer = [0u8; BUFFER_SIZE * NUM_CHANNELS * 2];
101 //!              for _i in 0..1000 {
102 //!
103 //!                  // Gets readable buffer from stream and
104 //!                  let mut buffer = stream.next_capture_buffer()?;
105 //!                  // Reads data to local buffer
106 //!                  let read_count = buffer.read(&mut local_buffer)?;
107 //!                  // Writes data to file
108 //!                  let _read_frames = file.write(&local_buffer[..read_count])?;
109 //!              }
110 //!              // Stream and client should gracefully be closed out of this scope
111 //! #        }
112 //! #        _ => {
113 //! #            println!("{} /path/to/capture_file.raw", args[0]);
114 //! #        }
115 //! #    };
116 //! #    Ok(())
117 //! # }
118 //! ```
119 use std::io;
120 use std::mem;
121 use std::os::unix::{
122     io::{AsRawFd, RawFd},
123     net::UnixStream,
124 };
125 use std::{error, fmt};
126 
127 pub use audio_streams::BoxError;
128 use audio_streams::{
129     capture::{CaptureBufferStream, NoopCaptureStream},
130     shm_streams::{NullShmStream, ShmStream, ShmStreamSource},
131     BufferDrop, NoopStreamControl, PlaybackBufferStream, SampleFormat, StreamControl,
132     StreamDirection, StreamEffect, StreamSource,
133 };
134 use cras_sys::gen::*;
135 pub use cras_sys::gen::{
136     CRAS_CLIENT_TYPE as CrasClientType, CRAS_NODE_TYPE as CrasNodeType,
137     CRAS_STREAM_EFFECT as CrasStreamEffect,
138 };
139 pub use cras_sys::{AudioDebugInfo, CrasIodevInfo, CrasIonodeInfo, Error as CrasSysError};
140 use sys_util::{PollContext, PollToken, SharedMemory};
141 
142 mod audio_socket;
143 use crate::audio_socket::AudioSocket;
144 mod cras_server_socket;
145 use crate::cras_server_socket::CrasServerSocket;
146 pub use crate::cras_server_socket::CrasSocketType;
147 mod cras_shm;
148 use crate::cras_shm::CrasServerState;
149 pub mod cras_shm_stream;
150 use crate::cras_shm_stream::CrasShmStream;
151 mod cras_stream;
152 use crate::cras_stream::{CrasCaptureData, CrasPlaybackData, CrasStream, CrasStreamData};
153 mod cras_client_message;
154 use crate::cras_client_message::*;
155 
156 #[derive(Debug)]
157 pub enum Error {
158     CrasClientMessageError(cras_client_message::Error),
159     CrasStreamError(cras_stream::Error),
160     CrasSysError(cras_sys::Error),
161     IoError(io::Error),
162     SysUtilError(sys_util::Error),
163     MessageTypeError,
164     UnexpectedExit,
165 }
166 
167 impl error::Error for Error {}
168 
169 impl fmt::Display for Error {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result170     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
171         match self {
172             Error::CrasClientMessageError(ref err) => err.fmt(f),
173             Error::CrasStreamError(ref err) => err.fmt(f),
174             Error::CrasSysError(ref err) => err.fmt(f),
175             Error::IoError(ref err) => err.fmt(f),
176             Error::SysUtilError(ref err) => err.fmt(f),
177             Error::MessageTypeError => write!(f, "Message type error"),
178             Error::UnexpectedExit => write!(f, "Unexpected exit"),
179         }
180     }
181 }
182 
183 type Result<T> = std::result::Result<T, Error>;
184 
185 impl From<io::Error> for Error {
from(io_err: io::Error) -> Self186     fn from(io_err: io::Error) -> Self {
187         Error::IoError(io_err)
188     }
189 }
190 
191 impl From<sys_util::Error> for Error {
from(sys_util_err: sys_util::Error) -> Self192     fn from(sys_util_err: sys_util::Error) -> Self {
193         Error::SysUtilError(sys_util_err)
194     }
195 }
196 
197 impl From<cras_stream::Error> for Error {
from(err: cras_stream::Error) -> Self198     fn from(err: cras_stream::Error) -> Self {
199         Error::CrasStreamError(err)
200     }
201 }
202 
203 impl From<cras_client_message::Error> for Error {
from(err: cras_client_message::Error) -> Self204     fn from(err: cras_client_message::Error) -> Self {
205         Error::CrasClientMessageError(err)
206     }
207 }
208 
209 /// A CRAS server client, which implements StreamSource and ShmStreamSource.
210 /// It can create audio streams connecting to CRAS server.
211 pub struct CrasClient<'a> {
212     server_socket: CrasServerSocket,
213     server_state: CrasServerState<'a>,
214     client_id: u32,
215     next_stream_id: u32,
216     cras_capture: bool,
217     client_type: CRAS_CLIENT_TYPE,
218 }
219 
220 impl<'a> CrasClient<'a> {
221     /// Blocks creating a `CrasClient` with registered `client_id`
222     ///
223     /// # Results
224     ///
225     /// * `CrasClient` - A client to interact with CRAS server
226     ///
227     /// # Errors
228     ///
229     /// Returns error if error occurs while handling server message or message
230     /// type is incorrect
new() -> Result<Self>231     pub fn new() -> Result<Self> {
232         Self::with_type(CrasSocketType::Legacy)
233     }
234 
235     /// Tries to create a `CrasClient` with a given `CrasSocketType`.
236     ///
237     /// # Errors
238     ///
239     /// Returns error if error occurs while handling server message or message
240     /// type is incorrect.
with_type(socket_type: CrasSocketType) -> Result<Self>241     pub fn with_type(socket_type: CrasSocketType) -> Result<Self> {
242         // Create a connection to the server.
243         let mut server_socket = CrasServerSocket::with_type(socket_type)?;
244         // Gets client ID and server state fd from server
245         if let ServerResult::Connected(client_id, server_state_fd) =
246             CrasClient::wait_for_message(&mut server_socket)?
247         {
248             Ok(Self {
249                 server_socket,
250                 server_state: CrasServerState::try_new(server_state_fd)?,
251                 client_id,
252                 next_stream_id: 0,
253                 cras_capture: false,
254                 client_type: CRAS_CLIENT_TYPE::CRAS_CLIENT_TYPE_UNKNOWN,
255             })
256         } else {
257             Err(Error::MessageTypeError)
258         }
259     }
260 
261     /// Enables capturing audio through CRAS server.
enable_cras_capture(&mut self)262     pub fn enable_cras_capture(&mut self) {
263         self.cras_capture = true;
264     }
265 
266     /// Set the type of this client to report to CRAS when connecting streams.
set_client_type(&mut self, client_type: CRAS_CLIENT_TYPE)267     pub fn set_client_type(&mut self, client_type: CRAS_CLIENT_TYPE) {
268         self.client_type = client_type;
269     }
270 
271     /// Sets the system volume to `volume`.
272     ///
273     /// Send a message to the server to request setting the system volume
274     /// to `volume`. No response is returned from the server.
275     ///
276     /// # Errors
277     ///
278     /// If writing the message to the server socket failed.
set_system_volume(&mut self, volume: u32) -> Result<()>279     pub fn set_system_volume(&mut self, volume: u32) -> Result<()> {
280         let header = cras_server_message {
281             length: mem::size_of::<cras_set_system_volume>() as u32,
282             id: CRAS_SERVER_MESSAGE_ID::CRAS_SERVER_SET_SYSTEM_VOLUME,
283         };
284         let msg = cras_set_system_volume { header, volume };
285 
286         self.server_socket.send_server_message_with_fds(&msg, &[])?;
287         Ok(())
288     }
289 
290     /// Sets the system mute status to `mute`.
291     ///
292     /// Send a message to the server to request setting the system mute
293     /// to `mute`. No response is returned from the server.
294     ///
295     /// # Errors
296     ///
297     /// If writing the message to the server socket failed.
set_system_mute(&mut self, mute: bool) -> Result<()>298     pub fn set_system_mute(&mut self, mute: bool) -> Result<()> {
299         let header = cras_server_message {
300             length: mem::size_of::<cras_set_system_mute>() as u32,
301             id: CRAS_SERVER_MESSAGE_ID::CRAS_SERVER_SET_SYSTEM_MUTE,
302         };
303         let msg = cras_set_system_mute {
304             header,
305             mute: mute as i32,
306         };
307 
308         self.server_socket.send_server_message_with_fds(&msg, &[])?;
309         Ok(())
310     }
311 
312     /// Gets the system volume.
313     ///
314     /// Read the current value for system volume from the server shared memory.
get_system_volume(&self) -> u32315     pub fn get_system_volume(&self) -> u32 {
316         self.server_state.get_system_volume()
317     }
318 
319     /// Gets the system mute.
320     ///
321     /// Read the current value for system mute from the server shared memory.
get_system_mute(&self) -> bool322     pub fn get_system_mute(&self) -> bool {
323         self.server_state.get_system_mute()
324     }
325 
326     /// Gets a list of output devices
327     ///
328     /// Read a list of the currently attached output devices from the server shared memory.
output_devices(&self) -> impl Iterator<Item = CrasIodevInfo>329     pub fn output_devices(&self) -> impl Iterator<Item = CrasIodevInfo> {
330         self.server_state.output_devices()
331     }
332 
333     /// Gets a list of input devices
334     ///
335     /// Read a list of the currently attached input devices from the server shared memory.
input_devices(&self) -> impl Iterator<Item = CrasIodevInfo>336     pub fn input_devices(&self) -> impl Iterator<Item = CrasIodevInfo> {
337         self.server_state.input_devices()
338     }
339 
340     /// Gets a list of output nodes
341     ///
342     /// Read a list of the currently attached output nodes from the server shared memory.
output_nodes(&self) -> impl Iterator<Item = CrasIonodeInfo>343     pub fn output_nodes(&self) -> impl Iterator<Item = CrasIonodeInfo> {
344         self.server_state.output_nodes()
345     }
346 
347     /// Gets a list of input nodes
348     ///
349     /// Read a list of the currently attached input nodes from the server shared memory.
input_nodes(&self) -> impl Iterator<Item = CrasIonodeInfo>350     pub fn input_nodes(&self) -> impl Iterator<Item = CrasIonodeInfo> {
351         self.server_state.input_nodes()
352     }
353 
354     /// Gets the server's audio debug info.
355     ///
356     /// Sends a message to the server requesting an update of audio debug info,
357     /// waits for the response, and then reads the info from the server state.
358     ///
359     /// # Errors
360     ///
361     /// * If sending the message to the server failed.
362     /// * If an unexpected response message is received.
get_audio_debug_info(&mut self) -> Result<AudioDebugInfo>363     pub fn get_audio_debug_info(&mut self) -> Result<AudioDebugInfo> {
364         let header = cras_server_message {
365             length: mem::size_of::<cras_dump_audio_thread>() as u32,
366             id: CRAS_SERVER_MESSAGE_ID::CRAS_SERVER_DUMP_AUDIO_THREAD,
367         };
368         let msg = cras_dump_audio_thread { header };
369 
370         self.server_socket.send_server_message_with_fds(&msg, &[])?;
371 
372         match CrasClient::wait_for_message(&mut self.server_socket)? {
373             ServerResult::DebugInfoReady => Ok(self
374                 .server_state
375                 .get_audio_debug_info()
376                 .map_err(Error::CrasSysError)?),
377             _ => Err(Error::MessageTypeError),
378         }
379     }
380 
381     // Gets next server_stream_id from client and increment stream_id counter.
next_server_stream_id(&mut self) -> u32382     fn next_server_stream_id(&mut self) -> u32 {
383         let res = self.next_stream_id;
384         self.next_stream_id += 1;
385         self.server_stream_id(res)
386     }
387 
388     // Gets server_stream_id from given stream_id
server_stream_id(&self, stream_id: u32) -> u32389     fn server_stream_id(&self, stream_id: u32) -> u32 {
390         (self.client_id << 16) | stream_id
391     }
392 
393     // Creates general stream with given parameters
create_stream<'b, T: BufferDrop + CrasStreamData<'b>>( &mut self, device_index: Option<u32>, block_size: u32, direction: CRAS_STREAM_DIRECTION, rate: u32, channel_num: usize, format: SampleFormat, ) -> Result<CrasStream<'b, T>>394     fn create_stream<'b, T: BufferDrop + CrasStreamData<'b>>(
395         &mut self,
396         device_index: Option<u32>,
397         block_size: u32,
398         direction: CRAS_STREAM_DIRECTION,
399         rate: u32,
400         channel_num: usize,
401         format: SampleFormat,
402     ) -> Result<CrasStream<'b, T>> {
403         let stream_id = self.next_server_stream_id();
404 
405         // Prepares server message
406         let audio_format =
407             cras_audio_format_packed::new(format.into(), rate, channel_num, direction);
408         let msg_header = cras_server_message {
409             length: mem::size_of::<cras_connect_message>() as u32,
410             id: CRAS_SERVER_MESSAGE_ID::CRAS_SERVER_CONNECT_STREAM,
411         };
412         let server_cmsg = cras_connect_message {
413             header: msg_header,
414             proto_version: CRAS_PROTO_VER,
415             direction,
416             stream_id,
417             stream_type: CRAS_STREAM_TYPE::CRAS_STREAM_TYPE_DEFAULT,
418             buffer_frames: block_size,
419             cb_threshold: block_size,
420             flags: 0,
421             format: audio_format,
422             dev_idx: device_index.unwrap_or(CRAS_SPECIAL_DEVICE::NO_DEVICE as u32),
423             effects: 0,
424             client_type: self.client_type,
425             client_shm_size: 0,
426             buffer_offsets: [0, 0],
427         };
428 
429         // Creates AudioSocket pair
430         let (sock1, sock2) = UnixStream::pair()?;
431 
432         // Sends `CRAS_SERVER_CONNECT_STREAM` message
433         let socks = [sock2.as_raw_fd()];
434         self.server_socket
435             .send_server_message_with_fds(&server_cmsg, &socks)?;
436 
437         let audio_socket = AudioSocket::new(sock1);
438         loop {
439             let result = CrasClient::wait_for_message(&mut self.server_socket)?;
440             if let ServerResult::StreamConnected(_stream_id, header_fd, samples_fd) = result {
441                 return CrasStream::try_new(
442                     stream_id,
443                     self.server_socket.try_clone()?,
444                     block_size,
445                     direction,
446                     rate,
447                     channel_num,
448                     format.into(),
449                     audio_socket,
450                     header_fd,
451                     samples_fd,
452                 )
453                 .map_err(Error::CrasStreamError);
454             }
455         }
456     }
457 
458     /// Creates a new playback stream pinned to the device at `device_index`.
459     ///
460     /// # Arguments
461     ///
462     /// * `device_index` - The device to which the stream will be attached.
463     /// * `num_channels` - The count of audio channels for the stream.
464     /// * `format` - The format to use for stream audio samples.
465     /// * `frame_rate` - The sample rate of the stream.
466     /// * `buffer_size` - The transfer size granularity in frames.
467     #[allow(clippy::type_complexity)]
new_pinned_playback_stream( &mut self, device_index: u32, num_channels: usize, format: SampleFormat, frame_rate: u32, buffer_size: usize, ) -> std::result::Result<(Box<dyn StreamControl>, Box<dyn PlaybackBufferStream>), BoxError>468     pub fn new_pinned_playback_stream(
469         &mut self,
470         device_index: u32,
471         num_channels: usize,
472         format: SampleFormat,
473         frame_rate: u32,
474         buffer_size: usize,
475     ) -> std::result::Result<(Box<dyn StreamControl>, Box<dyn PlaybackBufferStream>), BoxError>
476     {
477         Ok((
478             Box::new(NoopStreamControl::new()),
479             Box::new(self.create_stream::<CrasPlaybackData>(
480                 Some(device_index),
481                 buffer_size as u32,
482                 CRAS_STREAM_DIRECTION::CRAS_STREAM_OUTPUT,
483                 frame_rate,
484                 num_channels,
485                 format,
486             )?),
487         ))
488     }
489 
490     /// Creates a new capture stream pinned to the device at `device_index`.
491     ///
492     /// This is useful for, among other things, capturing from a loopback
493     /// device.
494     ///
495     /// # Arguments
496     ///
497     /// * `device_index` - The device to which the stream will be attached.
498     /// * `num_channels` - The count of audio channels for the stream.
499     /// * `format` - The format to use for stream audio samples.
500     /// * `frame_rate` - The sample rate of the stream.
501     /// * `buffer_size` - The transfer size granularity in frames.
502     #[allow(clippy::type_complexity)]
new_pinned_capture_stream( &mut self, device_index: u32, num_channels: usize, format: SampleFormat, frame_rate: u32, buffer_size: usize, ) -> std::result::Result<(Box<dyn StreamControl>, Box<dyn CaptureBufferStream>), BoxError>503     pub fn new_pinned_capture_stream(
504         &mut self,
505         device_index: u32,
506         num_channels: usize,
507         format: SampleFormat,
508         frame_rate: u32,
509         buffer_size: usize,
510     ) -> std::result::Result<(Box<dyn StreamControl>, Box<dyn CaptureBufferStream>), BoxError> {
511         Ok((
512             Box::new(NoopStreamControl::new()),
513             Box::new(self.create_stream::<CrasCaptureData>(
514                 Some(device_index),
515                 buffer_size as u32,
516                 CRAS_STREAM_DIRECTION::CRAS_STREAM_INPUT,
517                 frame_rate,
518                 num_channels,
519                 format,
520             )?),
521         ))
522     }
523 
524     // Blocks handling the first server message received from `socket`.
wait_for_message(socket: &mut CrasServerSocket) -> Result<ServerResult>525     fn wait_for_message(socket: &mut CrasServerSocket) -> Result<ServerResult> {
526         #[derive(PollToken)]
527         enum Token {
528             ServerMsg,
529         }
530         let poll_ctx: PollContext<Token> =
531             PollContext::new().and_then(|pc| pc.add(socket, Token::ServerMsg).and(Ok(pc)))?;
532 
533         let events = poll_ctx.wait()?;
534         // Check the first readable message
535         let tokens: Vec<Token> = events.iter_readable().map(|e| e.token()).collect();
536         tokens
537             .get(0)
538             .ok_or(Error::UnexpectedExit)
539             .and_then(|ref token| {
540                 match token {
541                     Token::ServerMsg => ServerResult::handle_server_message(socket),
542                 }
543                 .map_err(Into::into)
544             })
545     }
546 
547     /// Returns any open file descriptors needed by CrasClient.
548     /// This function is shared between StreamSource and ShmStreamSource.
keep_fds(&self) -> Vec<RawFd>549     fn keep_fds(&self) -> Vec<RawFd> {
550         vec![self.server_socket.as_raw_fd()]
551     }
552 }
553 
554 impl<'a> StreamSource for CrasClient<'a> {
555     #[allow(clippy::type_complexity)]
new_playback_stream( &mut self, num_channels: usize, format: SampleFormat, frame_rate: u32, buffer_size: usize, ) -> std::result::Result<(Box<dyn StreamControl>, Box<dyn PlaybackBufferStream>), BoxError>556     fn new_playback_stream(
557         &mut self,
558         num_channels: usize,
559         format: SampleFormat,
560         frame_rate: u32,
561         buffer_size: usize,
562     ) -> std::result::Result<(Box<dyn StreamControl>, Box<dyn PlaybackBufferStream>), BoxError>
563     {
564         Ok((
565             Box::new(NoopStreamControl::new()),
566             Box::new(self.create_stream::<CrasPlaybackData>(
567                 None,
568                 buffer_size as u32,
569                 CRAS_STREAM_DIRECTION::CRAS_STREAM_OUTPUT,
570                 frame_rate,
571                 num_channels,
572                 format,
573             )?),
574         ))
575     }
576 
577     #[allow(clippy::type_complexity)]
new_capture_stream( &mut self, num_channels: usize, format: SampleFormat, frame_rate: u32, buffer_size: usize, ) -> std::result::Result<(Box<dyn StreamControl>, Box<dyn CaptureBufferStream>), BoxError>578     fn new_capture_stream(
579         &mut self,
580         num_channels: usize,
581         format: SampleFormat,
582         frame_rate: u32,
583         buffer_size: usize,
584     ) -> std::result::Result<(Box<dyn StreamControl>, Box<dyn CaptureBufferStream>), BoxError> {
585         if self.cras_capture {
586             Ok((
587                 Box::new(NoopStreamControl::new()),
588                 Box::new(self.create_stream::<CrasCaptureData>(
589                     None,
590                     buffer_size as u32,
591                     CRAS_STREAM_DIRECTION::CRAS_STREAM_INPUT,
592                     frame_rate,
593                     num_channels,
594                     format,
595                 )?),
596             ))
597         } else {
598             Ok((
599                 Box::new(NoopStreamControl::new()),
600                 Box::new(NoopCaptureStream::new(
601                     num_channels,
602                     format,
603                     frame_rate,
604                     buffer_size,
605                 )),
606             ))
607         }
608     }
609 
keep_fds(&self) -> Option<Vec<RawFd>>610     fn keep_fds(&self) -> Option<Vec<RawFd>> {
611         Some(CrasClient::keep_fds(self))
612     }
613 }
614 
615 impl<'a> ShmStreamSource for CrasClient<'a> {
new_stream( &mut self, direction: StreamDirection, num_channels: usize, format: SampleFormat, frame_rate: u32, buffer_size: usize, effects: &[StreamEffect], client_shm: &SharedMemory, buffer_offsets: [u64; 2], ) -> std::result::Result<Box<dyn ShmStream>, BoxError>616     fn new_stream(
617         &mut self,
618         direction: StreamDirection,
619         num_channels: usize,
620         format: SampleFormat,
621         frame_rate: u32,
622         buffer_size: usize,
623         effects: &[StreamEffect],
624         client_shm: &SharedMemory,
625         buffer_offsets: [u64; 2],
626     ) -> std::result::Result<Box<dyn ShmStream>, BoxError> {
627         if direction == StreamDirection::Capture && !self.cras_capture {
628             return Ok(Box::new(NullShmStream::new(
629                 buffer_size,
630                 num_channels,
631                 format,
632                 frame_rate,
633             )));
634         }
635 
636         let buffer_size = buffer_size as u32;
637 
638         // Prepares server message
639         let stream_id = self.next_server_stream_id();
640         let audio_format = cras_audio_format_packed::new(
641             format.into(),
642             frame_rate,
643             num_channels,
644             direction.into(),
645         );
646         let msg_header = cras_server_message {
647             length: mem::size_of::<cras_connect_message>() as u32,
648             id: CRAS_SERVER_MESSAGE_ID::CRAS_SERVER_CONNECT_STREAM,
649         };
650 
651         let server_cmsg = cras_connect_message {
652             header: msg_header,
653             proto_version: CRAS_PROTO_VER,
654             direction: direction.into(),
655             stream_id,
656             stream_type: CRAS_STREAM_TYPE::CRAS_STREAM_TYPE_DEFAULT,
657             buffer_frames: buffer_size,
658             cb_threshold: buffer_size,
659             flags: 0,
660             format: audio_format,
661             dev_idx: CRAS_SPECIAL_DEVICE::NO_DEVICE as u32,
662             effects: effects.iter().collect::<CrasStreamEffect>().into(),
663             client_type: self.client_type,
664             client_shm_size: client_shm.size(),
665             buffer_offsets,
666         };
667 
668         // Creates AudioSocket pair
669         let (sock1, sock2) = UnixStream::pair()?;
670 
671         // Sends `CRAS_SERVER_CONNECT_STREAM` message
672         let fds = [sock2.as_raw_fd(), client_shm.as_raw_fd()];
673         self.server_socket
674             .send_server_message_with_fds(&server_cmsg, &fds)?;
675 
676         loop {
677             let result = CrasClient::wait_for_message(&mut self.server_socket)?;
678             if let ServerResult::StreamConnected(_stream_id, header_fd, _samples_fd) = result {
679                 let audio_socket = AudioSocket::new(sock1);
680                 let stream = CrasShmStream::try_new(
681                     stream_id,
682                     self.server_socket.try_clone()?,
683                     audio_socket,
684                     direction,
685                     num_channels,
686                     frame_rate,
687                     format,
688                     header_fd,
689                     client_shm.size() as usize,
690                 )?;
691                 return Ok(Box::new(stream));
692             }
693         }
694     }
695 
keep_fds(&self) -> Vec<RawFd>696     fn keep_fds(&self) -> Vec<RawFd> {
697         CrasClient::keep_fds(self)
698     }
699 }
700