xref: /aosp_15_r20/external/crosvm/libcras_stub/src/libcras.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 // Minimal implementation of interfaces in libcras for external builds.
6 //
7 // These just exist to allow us to build and clippy check the audio feature
8 // when building outside of ChromeOS. When building for ChromeOS, this stub
9 // will be replaced by the actual libcras implementation:
10 // https://source.chromium.org/chromiumos/chromiumos/codesearch/+/main:src/third_party/adhd/cras/client/libcras/
11 //
12 // Any changes to the libcras API used in crosvm needs to be reflected in this
13 // stub as well so as to have a successful crosvm build outside of ChromeOS.
14 //
15 // Instantiating a CrasClient using this will always panic!
16 
17 use std::error;
18 use std::fmt;
19 use std::str::FromStr;
20 
21 use audio_streams::shm_streams::SharedMemory;
22 use audio_streams::shm_streams::ShmStream;
23 use audio_streams::shm_streams::ShmStreamSource;
24 use audio_streams::BoxError;
25 use audio_streams::SampleFormat;
26 use audio_streams::StreamDirection;
27 use audio_streams::StreamEffect;
28 use audio_streams::StreamSource;
29 use audio_streams::StreamSourceGenerator;
30 use serde::Deserialize;
31 use serde::Deserializer;
32 use serde::Serialize;
33 
34 #[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
35 #[allow(non_camel_case_types)]
36 pub enum CRAS_CLIENT_TYPE {
37     #[serde(rename = "arcvm")]
38     CRAS_CLIENT_TYPE_ARCVM,
39     #[serde(rename = "crosvm")]
40     CRAS_CLIENT_TYPE_CROSVM,
41 }
42 
43 pub type CrasClientType = CRAS_CLIENT_TYPE;
44 
45 #[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
46 #[allow(non_camel_case_types)]
47 pub enum CRAS_STREAM_TYPE {
48     #[serde(rename = "default")]
49     CRAS_STREAM_TYPE_DEFAULT,
50     #[serde(rename = "pro_audio")]
51     CRAS_STREAM_TYPE_PRO_AUDIO,
52 }
53 
54 pub type CrasStreamType = CRAS_STREAM_TYPE;
55 
56 #[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
57 #[serde(rename_all = "lowercase")]
58 pub enum CrasSocketType {
59     Legacy,
60     Unified,
61 }
62 
63 #[derive(Debug)]
64 pub enum Error {
65     InvalidClientType,
66     InvalidSocketType,
67 }
68 impl fmt::Display for Error {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result69     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
70         write!(f, "")
71     }
72 }
73 
74 impl error::Error for Error {}
75 
76 pub type CrasSysError = Error;
77 
78 impl FromStr for CrasClientType {
79     type Err = CrasSysError;
from_str(cras_type: &str) -> std::result::Result<Self, Self::Err>80     fn from_str(cras_type: &str) -> std::result::Result<Self, Self::Err> {
81         match cras_type {
82             "crosvm" => Ok(CrasClientType::CRAS_CLIENT_TYPE_CROSVM),
83             "arcvm" => Ok(CrasClientType::CRAS_CLIENT_TYPE_ARCVM),
84             _ => Err(Error::InvalidClientType),
85         }
86     }
87 }
88 
89 impl FromStr for CrasSocketType {
90     type Err = Error;
from_str(sock_type: &str) -> std::result::Result<Self, Self::Err>91     fn from_str(sock_type: &str) -> std::result::Result<Self, Self::Err> {
92         match sock_type {
93             "legacy" => Ok(CrasSocketType::Legacy),
94             "unified" => Ok(CrasSocketType::Unified),
95             _ => Err(Error::InvalidSocketType),
96         }
97     }
98 }
99 
100 pub struct CrasStreamSourceGenerator {}
101 
102 impl CrasStreamSourceGenerator {
new(_capture: bool, _client_type: CrasClientType, _socket_type: CrasSocketType) -> Self103     pub fn new(_capture: bool, _client_type: CrasClientType, _socket_type: CrasSocketType) -> Self {
104         panic!("Cannot create cras audio device on non-chromeos crosvm builds.")
105     }
106 
with_stream_type( _capture: bool, _client_type: CrasClientType, _socket_type: CrasSocketType, _stream_type: CrasStreamType, ) -> Self107     pub fn with_stream_type(
108         _capture: bool,
109         _client_type: CrasClientType,
110         _socket_type: CrasSocketType,
111         _stream_type: CrasStreamType,
112     ) -> Self {
113         panic!("Cannot create cras audio device on non-chromeos crosvm builds.")
114     }
115 }
116 
117 impl StreamSourceGenerator for CrasStreamSourceGenerator {
generate(&self) -> std::result::Result<Box<dyn StreamSource>, BoxError>118     fn generate(&self) -> std::result::Result<Box<dyn StreamSource>, BoxError> {
119         panic!("Cannot create cras audio device on non-chromeos crosvm builds.")
120     }
121 }
122 
deserialize_cras_client_type<'de, D: Deserializer<'de>>( deserializer: D, ) -> std::result::Result<CRAS_CLIENT_TYPE, D::Error>123 pub fn deserialize_cras_client_type<'de, D: Deserializer<'de>>(
124     deserializer: D,
125 ) -> std::result::Result<CRAS_CLIENT_TYPE, D::Error> {
126     let s = String::deserialize(deserializer)?;
127 
128     match s.parse() {
129         Ok(client_type) => Ok(client_type),
130         Err(e) => Err(serde::de::Error::custom(e.to_string())),
131     }
132 }
133 
134 type Result<T> = std::result::Result<T, Error>;
135 
136 pub struct CrasClient {}
137 impl CrasClient {
with_type(_: CrasSocketType) -> Result<Self>138     pub fn with_type(_: CrasSocketType) -> Result<Self> {
139         panic!("Cannot create cras audio device on non-chromeos crosvm builds.")
140     }
set_client_type(&mut self, _: CrasClientType)141     pub fn set_client_type(&mut self, _: CrasClientType) {}
enable_cras_capture(&mut self)142     pub fn enable_cras_capture(&mut self) {}
143 }
144 
145 impl<E: std::error::Error> ShmStreamSource<E> for CrasClient {
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>146     fn new_stream(
147         &mut self,
148         _direction: StreamDirection,
149         _num_channels: usize,
150         _format: SampleFormat,
151         _frame_rate: u32,
152         _buffer_size: usize,
153         _effects: &[StreamEffect],
154         _client_shm: &dyn SharedMemory<Error = E>,
155         _buffer_offsets: [u64; 2],
156     ) -> std::result::Result<Box<dyn ShmStream>, BoxError> {
157         panic!("Cannot create cras audio device on non-chromeos crosvm builds.")
158     }
159 }
160