summaryrefslogtreecommitdiff
path: root/cras/client/cras_tests/src/arguments.rs
diff options
context:
space:
mode:
Diffstat (limited to 'cras/client/cras_tests/src/arguments.rs')
-rw-r--r--cras/client/cras_tests/src/arguments.rs462
1 files changed, 0 insertions, 462 deletions
diff --git a/cras/client/cras_tests/src/arguments.rs b/cras/client/cras_tests/src/arguments.rs
deleted file mode 100644
index 59e9ec26..00000000
--- a/cras/client/cras_tests/src/arguments.rs
+++ /dev/null
@@ -1,462 +0,0 @@
-// Copyright 2019 The Chromium OS Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-use std::error;
-use std::fmt;
-use std::path::PathBuf;
-
-use audio_streams::SampleFormat;
-use getopts::{self, Matches, Options};
-
-#[derive(Debug)]
-pub enum Error {
- GetOpts(getopts::Fail),
- InvalidArgument(String, String, String),
- InvalidFiletype(String),
- MissingArgument(String),
- MissingCommand,
- MissingFilename,
- UnknownCommand(String),
-}
-
-impl error::Error for Error {}
-
-impl fmt::Display for Error {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- use Error::*;
- match self {
- GetOpts(e) => write!(f, "Getopts Error: {}", e),
- InvalidArgument(flag, value, error_msg) => {
- write!(f, "Invalid {} argument '{}': {}", flag, value, error_msg)
- }
- InvalidFiletype(extension) => write!(
- f,
- "Invalid file extension '{}'. Supported types are 'wav' and 'raw'",
- extension
- ),
- MissingArgument(subcommand) => write!(f, "Missing argument for {}", subcommand),
- MissingCommand => write!(f, "A command must be provided"),
- MissingFilename => write!(f, "A file name must be provided"),
- UnknownCommand(s) => write!(f, "Unknown command '{}'", s),
- }
- }
-}
-
-type Result<T> = std::result::Result<T, Error>;
-
-/// The different types of commands that can be given to cras_tests.
-/// Any options for those commands are passed as parameters to the enum values.
-#[derive(Debug, PartialEq)]
-pub enum Command {
- Capture(AudioOptions),
- Playback(AudioOptions),
- Control(ControlCommand),
-}
-
-impl Command {
- pub fn parse<T: AsRef<str>>(args: &[T]) -> Result<Option<Self>> {
- let program_name = args.get(0).map(|s| s.as_ref()).unwrap_or("cras_tests");
- let remaining_args = args.get(2..).unwrap_or(&[]);
- match args.get(1).map(|s| s.as_ref()) {
- None => {
- show_usage(program_name);
- Err(Error::MissingCommand)
- }
- Some("help") => {
- show_usage(program_name);
- Ok(None)
- }
- Some("capture") => Ok(
- AudioOptions::parse(program_name, "capture", remaining_args)?.map(Command::Capture),
- ),
- Some("playback") => Ok(
- AudioOptions::parse(program_name, "playback", remaining_args)?
- .map(Command::Playback),
- ),
- Some("control") => {
- Ok(ControlCommand::parse(program_name, remaining_args)?.map(Command::Control))
- }
- Some(s) => {
- show_usage(program_name);
- Err(Error::UnknownCommand(s.to_string()))
- }
- }
- }
-}
-
-#[derive(Debug, PartialEq)]
-pub enum FileType {
- Raw,
- Wav,
-}
-
-impl fmt::Display for FileType {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- match self {
- FileType::Raw => write!(f, "raw data"),
- FileType::Wav => write!(f, "WAVE"),
- }
- }
-}
-
-fn show_usage(program_name: &str) {
- eprintln!("Usage: {} [command] <command args>", program_name);
- eprintln!("\nCommands:\n");
- eprintln!("capture - Capture to a file from CRAS");
- eprintln!("playback - Playback to CRAS from a file");
- eprintln!("control - Get and set server settings");
- eprintln!("\nhelp - Print help message");
-}
-
-fn show_audio_command_usage(program_name: &str, command: &str, opts: &Options) {
- let brief = format!("Usage: {} {} [options] [filename]", program_name, command);
- eprint!("{}", opts.usage(&brief));
-}
-
-/// The possible command line options that can be passed to the 'playback' and
-/// 'capture' commands. Optional values will be `Some(_)` only if a value was
-/// explicitly provided by the user.
-///
-/// This struct will be passed to `playback()` and `capture()`.
-#[derive(Debug, PartialEq)]
-pub enum LoopbackType {
- PreDsp,
- PostDsp,
-}
-
-#[derive(Debug, PartialEq)]
-pub struct AudioOptions {
- pub file_name: PathBuf,
- pub loopback_type: Option<LoopbackType>,
- pub file_type: FileType,
- pub buffer_size: Option<usize>,
- pub num_channels: Option<usize>,
- pub format: Option<SampleFormat>,
- pub frame_rate: Option<u32>,
-}
-
-fn get_u32_param(matches: &Matches, option_name: &str) -> Result<Option<u32>> {
- matches.opt_get::<u32>(option_name).map_err(|e| {
- let argument = matches.opt_str(option_name).unwrap_or_default();
- Error::InvalidArgument(option_name.to_string(), argument, e.to_string())
- })
-}
-
-fn get_usize_param(matches: &Matches, option_name: &str) -> Result<Option<usize>> {
- matches.opt_get::<usize>(option_name).map_err(|e| {
- let argument = matches.opt_str(option_name).unwrap_or_default();
- Error::InvalidArgument(option_name.to_string(), argument, e.to_string())
- })
-}
-
-impl AudioOptions {
- fn parse<T: AsRef<str>>(
- program_name: &str,
- command_name: &str,
- args: &[T],
- ) -> Result<Option<Self>> {
- let mut opts = Options::new();
- opts.optopt("b", "buffer_size", "Buffer size in frames", "SIZE")
- .optopt("c", "channels", "Number of channels", "NUM")
- .optopt(
- "f",
- "format",
- "Sample format (U8, S16_LE, S24_LE, or S32_LE)",
- "FORMAT",
- )
- .optopt("r", "rate", "Audio frame rate (Hz)", "RATE")
- .optflag("h", "help", "Print help message");
-
- if command_name == "capture" {
- opts.optopt(
- "",
- "loopback",
- "Capture from loopback device ('pre_dsp' or 'post_dsp')",
- "DEVICE",
- );
- }
-
- let args = args.iter().map(|s| s.as_ref());
- let matches = match opts.parse(args) {
- Ok(m) => m,
- Err(e) => {
- show_audio_command_usage(program_name, command_name, &opts);
- return Err(Error::GetOpts(e));
- }
- };
- if matches.opt_present("h") {
- show_audio_command_usage(program_name, command_name, &opts);
- return Ok(None);
- }
-
- let loopback_type = if matches.opt_defined("loopback") {
- match matches.opt_str("loopback").as_deref() {
- Some("pre_dsp") => Some(LoopbackType::PreDsp),
- Some("post_dsp") => Some(LoopbackType::PostDsp),
- Some(s) => {
- return Err(Error::InvalidArgument(
- "loopback".to_string(),
- s.to_string(),
- "Loopback type must be 'pre_dsp' or 'post_dsp'".to_string(),
- ))
- }
- None => None,
- }
- } else {
- None
- };
-
- let file_name = match matches.free.get(0) {
- None => {
- show_audio_command_usage(program_name, command_name, &opts);
- return Err(Error::MissingFilename);
- }
- Some(file_name) => PathBuf::from(file_name),
- };
-
- let extension = file_name
- .extension()
- .map(|s| s.to_string_lossy().into_owned());
- let file_type = match extension.as_deref() {
- Some("wav") | Some("wave") => FileType::Wav,
- Some("raw") | None => FileType::Raw,
- Some(extension) => return Err(Error::InvalidFiletype(extension.to_string())),
- };
-
- let buffer_size = get_usize_param(&matches, "buffer_size")?;
- let num_channels = get_usize_param(&matches, "channels")?;
- let frame_rate = get_u32_param(&matches, "rate")?;
- let format = match matches.opt_str("format").as_deref() {
- Some("U8") => Some(SampleFormat::U8),
- Some("S16_LE") => Some(SampleFormat::S16LE),
- Some("S24_LE") => Some(SampleFormat::S24LE),
- Some("S32_LE") => Some(SampleFormat::S32LE),
- Some(s) => {
- show_audio_command_usage(program_name, command_name, &opts);
- return Err(Error::InvalidArgument(
- "format".to_string(),
- s.to_string(),
- "Format must be 'U8', 'S16_LE', 'S24_LE', or 'S32_LE'".to_string(),
- ));
- }
- None => None,
- };
-
- Ok(Some(AudioOptions {
- loopback_type,
- file_name,
- file_type,
- buffer_size,
- num_channels,
- format,
- frame_rate,
- }))
- }
-}
-
-fn show_control_command_usage(program_name: &str) {
- eprintln!("Usage: {} control [command] <command args>", program_name);
- eprintln!("");
- eprintln!("Commands:");
- let commands = [
- ("help", "", "Print help message"),
- ("", "", ""),
- ("get_volume", "", "Get the system volume (0 - 100)"),
- (
- "set_volume",
- "VOLUME",
- "Set the system volume to VOLUME (0 - 100)",
- ),
- ("get_mute", "", "Get the system mute state (true or false)"),
- (
- "set_mute",
- "MUTE",
- "Set the system mute state to MUTE (true or false)",
- ),
- ("", "", ""),
- ("list_output_devices", "", "Print list of output devices"),
- ("list_input_devices", "", "Print list of input devices"),
- ("list_output_nodes", "", "Print list of output nodes"),
- ("list_input_nodes", "", "Print list of input nodes"),
- (
- "dump_audio_debug_info",
- "",
- "Print stream info, device info, and audio thread log.",
- ),
- ];
- for command in &commands {
- let command_string = format!("{} {}", command.0, command.1);
- eprintln!("\t{: <23} {}", command_string, command.2);
- }
-}
-
-#[derive(Debug, PartialEq)]
-pub enum ControlCommand {
- GetSystemVolume,
- SetSystemVolume(u32),
- GetSystemMute,
- SetSystemMute(bool),
- ListOutputDevices,
- ListInputDevices,
- ListOutputNodes,
- ListInputNodes,
- DumpAudioDebugInfo,
-}
-
-impl ControlCommand {
- fn parse<T: AsRef<str>>(program_name: &str, args: &[T]) -> Result<Option<Self>> {
- let mut args = args.iter().map(|s| s.as_ref());
- match args.next() {
- Some("help") => {
- show_control_command_usage(program_name);
- Ok(None)
- }
- Some("get_volume") => Ok(Some(ControlCommand::GetSystemVolume)),
- Some("set_volume") => {
- let volume_str = args
- .next()
- .ok_or_else(|| Error::MissingArgument("set_volume".to_string()))?;
-
- let volume = volume_str.parse::<u32>().map_err(|e| {
- Error::InvalidArgument(
- "set_volume".to_string(),
- volume_str.to_string(),
- e.to_string(),
- )
- })?;
-
- Ok(Some(ControlCommand::SetSystemVolume(volume)))
- }
- Some("get_mute") => Ok(Some(ControlCommand::GetSystemMute)),
- Some("set_mute") => {
- let mute_str = args
- .next()
- .ok_or_else(|| Error::MissingArgument("set_mute".to_string()))?;
-
- let mute = mute_str.parse::<bool>().map_err(|e| {
- Error::InvalidArgument(
- "set_mute".to_string(),
- mute_str.to_string(),
- e.to_string(),
- )
- })?;
- Ok(Some(ControlCommand::SetSystemMute(mute)))
- }
- Some("list_output_devices") => Ok(Some(ControlCommand::ListOutputDevices)),
- Some("list_input_devices") => Ok(Some(ControlCommand::ListInputDevices)),
- Some("list_output_nodes") => Ok(Some(ControlCommand::ListOutputNodes)),
- Some("list_input_nodes") => Ok(Some(ControlCommand::ListInputNodes)),
- Some("dump_audio_debug_info") => Ok(Some(ControlCommand::DumpAudioDebugInfo)),
- Some(s) => {
- show_control_command_usage(program_name);
- Err(Error::UnknownCommand(s.to_string()))
- }
- None => {
- show_control_command_usage(program_name);
- Err(Error::MissingCommand)
- }
- }
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
-
- #[test]
- fn parse_command() {
- let command = Command::parse(&["cras_tests", "playback", "output.wav"])
- .unwrap()
- .unwrap();
- assert_eq!(
- command,
- Command::Playback(AudioOptions {
- file_name: PathBuf::from("output.wav"),
- loopback_type: None,
- file_type: FileType::Wav,
- frame_rate: None,
- num_channels: None,
- format: None,
- buffer_size: None,
- })
- );
- let command = Command::parse(&["cras_tests", "capture", "input.raw"])
- .unwrap()
- .unwrap();
- assert_eq!(
- command,
- Command::Capture(AudioOptions {
- file_name: PathBuf::from("input.raw"),
- loopback_type: None,
- file_type: FileType::Raw,
- frame_rate: None,
- num_channels: None,
- format: None,
- buffer_size: None,
- })
- );
-
- let command = Command::parse(&[
- "cras_tests",
- "playback",
- "-r",
- "44100",
- "output.wave",
- "-c",
- "2",
- ])
- .unwrap()
- .unwrap();
- assert_eq!(
- command,
- Command::Playback(AudioOptions {
- file_name: PathBuf::from("output.wave"),
- loopback_type: None,
- file_type: FileType::Wav,
- frame_rate: Some(44100),
- num_channels: Some(2),
- format: None,
- buffer_size: None,
- })
- );
-
- let command =
- Command::parse(&["cras_tests", "playback", "-r", "44100", "output", "-c", "2"])
- .unwrap()
- .unwrap();
- assert_eq!(
- command,
- Command::Playback(AudioOptions {
- file_name: PathBuf::from("output"),
- loopback_type: None,
- file_type: FileType::Raw,
- frame_rate: Some(44100),
- num_channels: Some(2),
- format: None,
- buffer_size: None,
- })
- );
-
- assert!(Command::parse(&["cras_tests"]).is_err());
- assert!(Command::parse(&["cras_tests", "capture"]).is_err());
- assert!(Command::parse(&["cras_tests", "capture", "input.mp3"]).is_err());
- assert!(Command::parse(&["cras_tests", "capture", "input.ogg"]).is_err());
- assert!(Command::parse(&["cras_tests", "capture", "input.flac"]).is_err());
- assert!(Command::parse(&["cras_tests", "playback"]).is_err());
- assert!(Command::parse(&["cras_tests", "loopback"]).is_err());
- assert!(Command::parse(&["cras_tests", "loopback", "file.ogg"]).is_err());
- assert!(Command::parse(&["cras_tests", "filename.wav"]).is_err());
- assert!(Command::parse(&["cras_tests", "filename.wav", "capture"]).is_err());
- assert!(Command::parse(&["cras_tests", "help"]).is_ok());
- assert!(Command::parse(&[
- "cras_tests",
- "-c",
- "2",
- "playback",
- "output.wav",
- "-r",
- "44100"
- ])
- .is_err());
- }
-}