libcras_stub: Stub implementation

Stub the required parts of libcras so that upstream builds with
audio_cras feature

BUG=b:244618503
TEST=cargo build --features audio_cras

Change-Id: I21eb3bcb9a61990740b1419f124401878619481e
Reviewed-on: https://chromium-review.googlesource.com/c/crosvm/crosvm/+/3911099
Reviewed-by: Dennis Kempin <denniskempin@google.com>
Commit-Queue: Vineeth Pillai <vineethrp@google.com>
This commit is contained in:
Vineeth Pillai 2022-09-21 18:48:02 +00:00 committed by crosvm LUCI
parent 1c3ba38583
commit aea39132e8
4 changed files with 137 additions and 1 deletions

4
Cargo.lock generated
View file

@ -1046,6 +1046,10 @@ checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836"
[[package]]
name = "libcras"
version = "0.1.0"
dependencies = [
"audio_streams",
"serde",
]
[[package]]
name = "libdbus-sys"

View file

@ -110,6 +110,7 @@ exclude = [
[features]
all-linux = [
# TODO(b/203105868): Enable remaining features on linux builds.
"audio_cras",
"composite-disk",
"default",
"gdb",

View file

@ -6,3 +6,7 @@ edition = "2021"
[lib]
path = "src/libcras.rs"
[dependencies]
audio_streams = "*"
serde = "*"

View file

@ -2,4 +2,131 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// This space intentionally left blank.
// Minimal implementation of interfaces in libcras for external builds.
//
// These just exist to allow us to build and clippy check the audio feature
// when building outside of ChromeOS. When building for ChromeOS, this stub
// will be replaced by the actual libcras implementation:
// https://source.chromium.org/chromiumos/chromiumos/codesearch/+/main:src/third_party/adhd/cras/client/libcras/
//
// Any changes to the libcras API used in crosvm needs to be reflected in this
// stub as well so as to have a successful crosvm build outside of ChromeOS.
//
// Instantiating a CrasClient using this will always panic!
use audio_streams::{
shm_streams::{SharedMemory, ShmStream, ShmStreamSource},
BoxError, SampleFormat, StreamDirection, StreamEffect, StreamSource, StreamSourceGenerator,
};
use std::error;
use std::fmt;
use std::str::FromStr;
use serde::Deserialize;
use serde::Deserializer;
use serde::Serialize;
#[derive(Debug, Clone, Copy, PartialEq, Deserialize, Serialize)]
#[allow(non_camel_case_types)]
pub enum CRAS_CLIENT_TYPE {
CRAS_CLIENT_TYPE_ARCVM,
CRAS_CLIENT_TYPE_CROSVM,
}
pub type CrasClientType = CRAS_CLIENT_TYPE;
#[derive(Debug, Clone, Copy, PartialEq, Deserialize, Serialize)]
#[serde(rename_all = "lowercase")]
pub enum CrasSocketType {
Legacy,
Unified,
}
#[derive(Debug)]
pub enum Error {
InvalidClientType,
InvalidSocketType,
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "")
}
}
impl error::Error for Error {}
pub type CrasSysError = Error;
impl FromStr for CrasClientType {
type Err = CrasSysError;
fn from_str(cras_type: &str) -> std::result::Result<Self, Self::Err> {
match cras_type {
"crosvm" => Ok(CrasClientType::CRAS_CLIENT_TYPE_CROSVM),
"arcvm" => Ok(CrasClientType::CRAS_CLIENT_TYPE_ARCVM),
_ => Err(Error::InvalidClientType),
}
}
}
impl FromStr for CrasSocketType {
type Err = Error;
fn from_str(sock_type: &str) -> std::result::Result<Self, Self::Err> {
match sock_type {
"legacy" => Ok(CrasSocketType::Legacy),
"unified" => Ok(CrasSocketType::Unified),
_ => Err(Error::InvalidSocketType),
}
}
}
pub struct CrasStreamSourceGenerator {}
impl CrasStreamSourceGenerator {
pub fn new(_capture: bool, _client_type: CrasClientType, _socket_type: CrasSocketType) -> Self {
panic!("Cannot create cras audio device on non-chromeos crosvm builds.")
}
}
impl StreamSourceGenerator for CrasStreamSourceGenerator {
fn generate(&self) -> std::result::Result<Box<dyn StreamSource>, BoxError> {
panic!("Cannot create cras audio device on non-chromeos crosvm builds.")
}
}
pub fn deserialize_cras_client_type<'de, D: Deserializer<'de>>(
deserializer: D,
) -> std::result::Result<CRAS_CLIENT_TYPE, D::Error> {
let s = String::deserialize(deserializer)?;
match s.parse() {
Ok(client_type) => Ok(client_type),
Err(e) => Err(serde::de::Error::custom(e.to_string())),
}
}
type Result<T> = std::result::Result<T, Error>;
pub struct CrasClient {}
impl CrasClient {
pub fn with_type(_: CrasSocketType) -> Result<Self> {
panic!("Cannot create cras audio device on non-chromeos crosvm builds.")
}
pub fn set_client_type(&mut self, _: CrasClientType) {}
pub fn enable_cras_capture(&mut self) {}
}
impl<E: std::error::Error> ShmStreamSource<E> for CrasClient {
fn new_stream(
&mut self,
_direction: StreamDirection,
_num_channels: usize,
_format: SampleFormat,
_frame_rate: u32,
_buffer_size: usize,
_effects: &[StreamEffect],
_client_shm: &dyn SharedMemory<Error = E>,
_buffer_offsets: [u64; 2],
) -> std::result::Result<Box<dyn ShmStream>, BoxError> {
panic!("Cannot create cras audio device on non-chromeos crosvm builds.")
}
}