blob: 3a98ec98d16ab6027f7c83c335b78a0f6dadf497 [file] [log] [blame]
// 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 libcras::{AudioDebugInfo, CrasClient, CrasIonodeInfo};
use crate::arguments::ControlCommand;
/// An enumeration of errors that can occur when running `ControlCommand` using
/// the `control()` function.
#[derive(Debug)]
pub enum Error {
Libcras(libcras::Error),
}
impl error::Error for Error {}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use Error::*;
match self {
Libcras(e) => write!(f, "Libcras Error: {}", e),
}
}
}
type Result<T> = std::result::Result<T, Error>;
fn print_nodes(nodes: impl Iterator<Item = CrasIonodeInfo>) {
println!(
"{: <13}{: <7}{: <6}{: <10}{: <13}{: <20} {: <10}",
"Stable ID", "ID", "Vol", "Plugged", "Time", "Type", "Name"
);
for node in nodes {
let id = format!("{}:{}", node.iodev_index, node.ionode_index);
let stable_id = format!("({:08x})", node.stable_id);
let plugged_time = node.plugged_time.tv_sec;
let active = if node.active { "*" } else { " " };
println!(
"{: <13}{: <7}{: <6}{: <10}{: <13}{: <20}{}{: <10}",
stable_id,
id,
node.volume,
node.plugged,
plugged_time,
node.type_name,
active,
node.name
);
}
}
fn print_audio_debug_info(info: &AudioDebugInfo) {
println!("Audio Debug Stats:");
println!("-------------devices------------");
for device in &info.devices {
println!("{}", device);
println!();
}
println!("-------------stream_dump------------");
for stream in &info.streams {
println!("{}", stream);
println!();
}
}
/// Connect to CRAS and run the given `ControlCommand`.
pub fn control(command: ControlCommand) -> Result<()> {
use ControlCommand::*;
let mut cras_client = CrasClient::new().map_err(Error::Libcras)?;
match command {
GetSystemVolume => println!("{}", cras_client.get_system_volume()),
SetSystemVolume(volume) => {
cras_client
.set_system_volume(volume)
.map_err(Error::Libcras)?;
}
GetSystemMute => println!("{}", cras_client.get_system_mute()),
SetSystemMute(mute) => {
cras_client.set_system_mute(mute).map_err(Error::Libcras)?;
}
ListOutputDevices => {
println!("{: <5}{: <10}", "ID", "Name");
for dev in cras_client.output_devices() {
println!("{: <5}{: <10}", dev.index, dev.name);
}
}
ListInputDevices => {
println!("{: <5}{: <10}", "ID", "Name");
for dev in cras_client.input_devices() {
println!("{: <5}{: <10}", dev.index, dev.name);
}
}
ListOutputNodes => print_nodes(cras_client.output_nodes()),
ListInputNodes => print_nodes(cras_client.input_nodes()),
DumpAudioDebugInfo => {
let debug_info = cras_client.get_audio_debug_info().map_err(Error::Libcras)?;
print_audio_debug_info(&debug_info);
}
};
Ok(())
}