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