xref: /aosp_15_r20/external/crosvm/cros_async/src/audio_streams_async.rs (revision bb4ee6a4ae7042d18b07a98463b9c8b875e44b39)
1 // Copyright 2022 The ChromiumOS Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 //! Implements the interface required by `audio_streams` using the cros_async Executor.
6 //!
7 //! It implements the `AudioStreamsExecutor` trait for `Executor`, so it can be passed into
8 //! the audio_streams API.
9 use std::io::Result;
10 #[cfg(any(target_os = "android", target_os = "linux"))]
11 use std::os::unix::net::UnixStream;
12 #[cfg(windows)]
13 use std::os::windows::io::RawHandle;
14 use std::time::Duration;
15 
16 use async_trait::async_trait;
17 #[cfg(any(target_os = "android", target_os = "linux"))]
18 use audio_streams::async_api::AsyncStream;
19 use audio_streams::async_api::AudioStreamsExecutor;
20 use audio_streams::async_api::EventAsyncWrapper;
21 use audio_streams::async_api::ReadAsync;
22 use audio_streams::async_api::ReadWriteAsync;
23 use audio_streams::async_api::WriteAsync;
24 #[cfg(any(target_os = "android", target_os = "linux"))]
25 use base::Descriptor;
26 #[cfg(windows)]
27 use base::Event;
28 #[cfg(windows)]
29 use base::FromRawDescriptor;
30 #[cfg(any(target_os = "android", target_os = "linux"))]
31 use base::RawDescriptor;
32 
33 #[cfg(any(target_os = "android", target_os = "linux"))]
34 use super::AsyncWrapper;
35 use crate::EventAsync;
36 use crate::IntoAsync;
37 use crate::IoSource;
38 use crate::TimerAsync;
39 
40 /// A wrapper around IoSource that is compatible with the audio_streams traits.
41 pub struct IoSourceWrapper<T: IntoAsync + Send> {
42     source: IoSource<T>,
43 }
44 
45 #[async_trait(?Send)]
46 impl<T: IntoAsync + Send> ReadAsync for IoSourceWrapper<T> {
read_to_vec<'a>( &'a self, file_offset: Option<u64>, vec: Vec<u8>, ) -> Result<(usize, Vec<u8>)>47     async fn read_to_vec<'a>(
48         &'a self,
49         file_offset: Option<u64>,
50         vec: Vec<u8>,
51     ) -> Result<(usize, Vec<u8>)> {
52         self.source
53             .read_to_vec(file_offset, vec)
54             .await
55             .map_err(Into::into)
56     }
57 }
58 
59 #[async_trait(?Send)]
60 impl<T: IntoAsync + Send> WriteAsync for IoSourceWrapper<T> {
write_from_vec<'a>( &'a self, file_offset: Option<u64>, vec: Vec<u8>, ) -> Result<(usize, Vec<u8>)>61     async fn write_from_vec<'a>(
62         &'a self,
63         file_offset: Option<u64>,
64         vec: Vec<u8>,
65     ) -> Result<(usize, Vec<u8>)> {
66         self.source
67             .write_from_vec(file_offset, vec)
68             .await
69             .map_err(Into::into)
70     }
71 }
72 
73 #[async_trait(?Send)]
74 impl<T: IntoAsync + Send> ReadWriteAsync for IoSourceWrapper<T> {}
75 
76 #[async_trait(?Send)]
77 impl EventAsyncWrapper for EventAsync {
wait(&self) -> Result<u64>78     async fn wait(&self) -> Result<u64> {
79         self.next_val().await.map_err(Into::into)
80     }
81 }
82 
83 #[async_trait(?Send)]
84 impl AudioStreamsExecutor for super::Executor {
85     #[cfg(any(target_os = "android", target_os = "linux"))]
async_unix_stream(&self, stream: UnixStream) -> Result<AsyncStream>86     fn async_unix_stream(&self, stream: UnixStream) -> Result<AsyncStream> {
87         Ok(Box::new(IoSourceWrapper {
88             source: self.async_from(AsyncWrapper::new(stream))?,
89         }))
90     }
91 
92     /// # Safety
93     /// This is only safe if `event` is a handle to a Windows Event.
94     #[cfg(windows)]
async_event(&self, event: RawHandle) -> Result<Box<dyn EventAsyncWrapper>>95     unsafe fn async_event(&self, event: RawHandle) -> Result<Box<dyn EventAsyncWrapper>> {
96         Ok(Box::new(
97             EventAsync::new(Event::from_raw_descriptor(event), self)
98                 .map_err(std::io::Error::from)?,
99         ))
100     }
101 
delay(&self, dur: Duration) -> Result<()>102     async fn delay(&self, dur: Duration) -> Result<()> {
103         TimerAsync::sleep(self, dur).await.map_err(Into::into)
104     }
105 
106     #[cfg(any(target_os = "android", target_os = "linux"))]
wait_fd_readable(&self, fd: RawDescriptor) -> Result<()>107     async fn wait_fd_readable(&self, fd: RawDescriptor) -> Result<()> {
108         self.async_from(AsyncWrapper::new(Descriptor(fd)))?
109             .wait_readable()
110             .await
111             .map_err(Into::into)
112     }
113 }
114