xref: /aosp_15_r20/external/crosvm/common/audio_streams/src/async_api.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 //! Traits required by `audio_streams` to perform async operations.
6 //!
7 //! Consumers must provide an implementation of `AudioStreamsExecutor` to allow the
8 //! async `audio_streams` interface to do async io on the Executor provided by the consumer.
9 //!
10 //! These traits follow the interface of `cros_async`, since it is used by both crosvm and libcras
11 //! to implement them.
12 //!
13 //! The implementation is provided in `cros_async::audio_streams_async`.
14 
15 use std::io::Result;
16 #[cfg(any(target_os = "android", target_os = "linux"))]
17 use std::os::unix::io::RawFd as RawDescriptor;
18 #[cfg(any(target_os = "android", target_os = "linux"))]
19 use std::os::unix::net::UnixStream;
20 #[cfg(windows)]
21 use std::os::windows::io::RawHandle;
22 use std::time::Duration;
23 
24 use async_trait::async_trait;
25 
26 #[async_trait(?Send)]
27 pub trait ReadAsync {
28     /// Read asynchronously into the provided Vec.
29     ///
30     /// The ownership of the Vec is returned after the operation completes, along with the number of
31     /// bytes read.
read_to_vec<'a>( &'a self, file_offset: Option<u64>, vec: Vec<u8>, ) -> Result<(usize, Vec<u8>)>32     async fn read_to_vec<'a>(
33         &'a self,
34         file_offset: Option<u64>,
35         vec: Vec<u8>,
36     ) -> Result<(usize, Vec<u8>)>;
37 }
38 
39 #[async_trait(?Send)]
40 pub trait WriteAsync {
41     /// Write asynchronously from the provided Vec.
42     ///
43     /// The ownership of the Vec is returned after the operation completes, along with the number of
44     /// bytes written.
write_from_vec<'a>( &'a self, file_offset: Option<u64>, vec: Vec<u8>, ) -> Result<(usize, Vec<u8>)>45     async fn write_from_vec<'a>(
46         &'a self,
47         file_offset: Option<u64>,
48         vec: Vec<u8>,
49     ) -> Result<(usize, Vec<u8>)>;
50 }
51 
52 /// Trait to wrap around EventAsync, because audio_streams can't depend on anything in `base` or
53 /// `cros_async`.
54 #[async_trait(?Send)]
55 pub trait EventAsyncWrapper {
wait(&self) -> Result<u64>56     async fn wait(&self) -> Result<u64>;
57 }
58 
59 pub trait ReadWriteAsync: ReadAsync + WriteAsync {}
60 
61 pub type AsyncStream = Box<dyn ReadWriteAsync + Send>;
62 
63 /// Trait of Executor functionality used by `audio_streams`.
64 #[async_trait(?Send)]
65 pub trait AudioStreamsExecutor {
66     /// Create an object to allow async reads/writes from the specified UnixStream.
67     #[cfg(any(target_os = "android", target_os = "linux"))]
async_unix_stream(&self, f: UnixStream) -> Result<AsyncStream>68     fn async_unix_stream(&self, f: UnixStream) -> Result<AsyncStream>;
69 
70     /// Wraps an event that will be triggered when the audio backend is ready to read more audio
71     /// data.
72     ///
73     /// # Safety
74     /// Callers needs to make sure the `RawHandle` is an Event, or at least a valid Handle for
75     /// their use case.
76     #[cfg(windows)]
async_event(&self, event: RawHandle) -> Result<Box<dyn EventAsyncWrapper>>77     unsafe fn async_event(&self, event: RawHandle) -> Result<Box<dyn EventAsyncWrapper>>;
78 
79     /// Returns a future that resolves after the specified time.
delay(&self, dur: Duration) -> Result<()>80     async fn delay(&self, dur: Duration) -> Result<()>;
81 
82     // Returns a future that resolves after the provided descriptor is readable.
83     #[cfg(any(target_os = "android", target_os = "linux"))]
wait_fd_readable(&self, _fd: RawDescriptor) -> Result<()>84     async fn wait_fd_readable(&self, _fd: RawDescriptor) -> Result<()> {
85         Ok(())
86     }
87 }
88 
89 #[cfg(test)]
90 pub mod test {
91     use super::*;
92 
93     /// Stub implementation of the AudioStreamsExecutor to use in unit tests.
94     pub struct TestExecutor {}
95 
96     #[async_trait(?Send)]
97     impl AudioStreamsExecutor for TestExecutor {
98         #[cfg(any(target_os = "android", target_os = "linux"))]
async_unix_stream(&self, _f: UnixStream) -> Result<AsyncStream>99         fn async_unix_stream(&self, _f: UnixStream) -> Result<AsyncStream> {
100             panic!("Not Implemented");
101         }
102 
delay(&self, dur: Duration) -> Result<()>103         async fn delay(&self, dur: Duration) -> Result<()> {
104             // Simulates the delay by blocking to satisfy behavior expected in unit tests.
105             std::thread::sleep(dur);
106             return Ok(());
107         }
108 
109         #[cfg(windows)]
async_event(&self, _event: RawHandle) -> Result<Box<dyn EventAsyncWrapper>>110         unsafe fn async_event(&self, _event: RawHandle) -> Result<Box<dyn EventAsyncWrapper>> {
111             unimplemented!("async_event is not yet implemented on windows");
112         }
113     }
114 }
115