From aea39132e8cc58697397ac8773062719496b9a5a Mon Sep 17 00:00:00 2001 From: Vineeth Pillai Date: Wed, 21 Sep 2022 18:48:02 +0000 Subject: [PATCH] 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 Commit-Queue: Vineeth Pillai --- Cargo.lock | 4 ++ Cargo.toml | 1 + libcras_stub/Cargo.toml | 4 ++ libcras_stub/src/libcras.rs | 129 +++++++++++++++++++++++++++++++++++- 4 files changed, 137 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 17cf32d8b1..1a29a861cf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1046,6 +1046,10 @@ checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836" [[package]] name = "libcras" version = "0.1.0" +dependencies = [ + "audio_streams", + "serde", +] [[package]] name = "libdbus-sys" diff --git a/Cargo.toml b/Cargo.toml index 0cf2e5963b..766e13db27 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -110,6 +110,7 @@ exclude = [ [features] all-linux = [ # TODO(b/203105868): Enable remaining features on linux builds. + "audio_cras", "composite-disk", "default", "gdb", diff --git a/libcras_stub/Cargo.toml b/libcras_stub/Cargo.toml index 4b0961cb74..2e0e1f13ac 100644 --- a/libcras_stub/Cargo.toml +++ b/libcras_stub/Cargo.toml @@ -6,3 +6,7 @@ edition = "2021" [lib] path = "src/libcras.rs" + +[dependencies] +audio_streams = "*" +serde = "*" diff --git a/libcras_stub/src/libcras.rs b/libcras_stub/src/libcras.rs index 852ee53f3a..3d0d68f52b 100644 --- a/libcras_stub/src/libcras.rs +++ b/libcras_stub/src/libcras.rs @@ -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 { + 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 { + 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, 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 { + 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 = std::result::Result; + +pub struct CrasClient {} +impl CrasClient { + pub fn with_type(_: CrasSocketType) -> Result { + 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 ShmStreamSource 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, + _buffer_offsets: [u64; 2], + ) -> std::result::Result, BoxError> { + panic!("Cannot create cras audio device on non-chromeos crosvm builds.") + } +}