// Copyright 2022 The ChromiumOS Authors1// Use of this source code is governed by a BSD-style license that can be2// found in the LICENSE file.34//! Traits required by `audio_streams` to perform async operations.5//!6//! Consumers must provide an implementation of `AudioStreamsExecutor` to allow the7//! async `audio_streams` interface to do async io on the Executor provided by the consumer.8//!9//! These traits follow the interface of `cros_async`, since it is used by both crosvm and libcras10//! to implement them.11//!12//! The implementation is provided in `cros_async::audio_streams_async`.1314use std::io::Result;15#[cfg(any(target_os = "android", target_os = "linux"))]16use std::os::unix::io::RawFd as RawDescriptor;17#[cfg(any(target_os = "android", target_os = "linux"))]18use std::os::unix::net::UnixStream;19#[cfg(windows)]20use std::os::windows::io::RawHandle;21use std::time::Duration;2223use async_trait::async_trait;2425#[async_trait(?Send)]26pub trait ReadAsync {27/// Read asynchronously into the provided Vec.28///29/// The ownership of the Vec is returned after the operation completes, along with the number of30/// bytes read.31async fn read_to_vec<'a>(32&'a self,33file_offset: Option<u64>,34vec: Vec<u8>,35) -> Result<(usize, Vec<u8>)>;36}3738#[async_trait(?Send)]39pub trait WriteAsync {40/// Write asynchronously from the provided Vec.41///42/// The ownership of the Vec is returned after the operation completes, along with the number of43/// bytes written.44async fn write_from_vec<'a>(45&'a self,46file_offset: Option<u64>,47vec: Vec<u8>,48) -> Result<(usize, Vec<u8>)>;49}5051/// Trait to wrap around EventAsync, because audio_streams can't depend on anything in `base` or52/// `cros_async`.53#[async_trait(?Send)]54pub trait EventAsyncWrapper {55async fn wait(&self) -> Result<u64>;56}5758pub trait ReadWriteAsync: ReadAsync + WriteAsync {}5960pub type AsyncStream = Box<dyn ReadWriteAsync + Send>;6162/// Trait of Executor functionality used by `audio_streams`.63#[async_trait(?Send)]64pub trait AudioStreamsExecutor {65/// Create an object to allow async reads/writes from the specified UnixStream.66#[cfg(any(target_os = "android", target_os = "linux"))]67fn async_unix_stream(&self, f: UnixStream) -> Result<AsyncStream>;6869/// Wraps an event that will be triggered when the audio backend is ready to read more audio70/// data.71///72/// # Safety73/// Callers needs to make sure the `RawHandle` is an Event, or at least a valid Handle for74/// their use case.75#[cfg(windows)]76unsafe fn async_event(&self, event: RawHandle) -> Result<Box<dyn EventAsyncWrapper>>;7778/// Returns a future that resolves after the specified time.79async fn delay(&self, dur: Duration) -> Result<()>;8081// Returns a future that resolves after the provided descriptor is readable.82#[cfg(any(target_os = "android", target_os = "linux"))]83async fn wait_fd_readable(&self, _fd: RawDescriptor) -> Result<()> {84Ok(())85}86}8788#[cfg(test)]89pub mod test {90use super::*;9192/// Stub implementation of the AudioStreamsExecutor to use in unit tests.93pub struct TestExecutor {}9495#[async_trait(?Send)]96impl AudioStreamsExecutor for TestExecutor {97#[cfg(any(target_os = "android", target_os = "linux"))]98fn async_unix_stream(&self, _f: UnixStream) -> Result<AsyncStream> {99panic!("Not Implemented");100}101102async fn delay(&self, dur: Duration) -> Result<()> {103// Simulates the delay by blocking to satisfy behavior expected in unit tests.104std::thread::sleep(dur);105return Ok(());106}107108#[cfg(windows)]109unsafe fn async_event(&self, _event: RawHandle) -> Result<Box<dyn EventAsyncWrapper>> {110unimplemented!("async_event is not yet implemented on windows");111}112}113}114115116