Skip to content

Commit

Permalink
Fix audio_get_status result
Browse files Browse the repository at this point in the history
  • Loading branch information
kira-bruneau committed Sep 12, 2024
1 parent 2ada364 commit 0888e34
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 13 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

- Fix `audio_get_status` result

## 7.1.1

- Require libcec >= 4.0.3 for fixed windows compatibility
Expand Down
96 changes: 83 additions & 13 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,13 @@ use std::{collections::HashSet, pin::Pin};

use arrayvec::ArrayVec;
use libcec_sys::{
cec_command, cec_datapacket, cec_device_type_list, cec_keypress, cec_log_message,
cec_logical_address, cec_logical_addresses, cec_power_status, libcec_audio_get_status,
libcec_audio_mute, libcec_audio_toggle_mute, libcec_audio_unmute, libcec_clear_configuration,
libcec_close, libcec_configuration, libcec_connection_t, libcec_destroy,
libcec_get_active_source, libcec_get_device_power_status, libcec_get_logical_addresses,
libcec_initialise, libcec_is_active_source, libcec_mute_audio, libcec_open,
libcec_power_on_devices, libcec_send_key_release, libcec_send_keypress,
cec_audio_status, cec_command, cec_datapacket, cec_device_type_list, cec_keypress,
cec_log_message, cec_logical_address, cec_logical_addresses, cec_power_status,
libcec_audio_get_status, libcec_audio_mute, libcec_audio_toggle_mute, libcec_audio_unmute,
libcec_clear_configuration, libcec_close, libcec_configuration, libcec_connection_t,
libcec_destroy, libcec_get_active_source, libcec_get_device_power_status,
libcec_get_logical_addresses, libcec_initialise, libcec_is_active_source, libcec_mute_audio,
libcec_open, libcec_power_on_devices, libcec_send_key_release, libcec_send_keypress,
libcec_set_active_source, libcec_set_inactive_view, libcec_set_logical_address,
libcec_standby_devices, libcec_switch_monitoring, libcec_transmit, libcec_volume_down,
libcec_volume_up, ICECCallbacks, LIBCEC_OSD_NAME_SIZE, LIBCEC_VERSION_CURRENT,
Expand Down Expand Up @@ -134,6 +134,80 @@ mod util_tests {
}
}

/// cec_audio_status which does not allow CEC_AUDIO_VOLUME_STATUS_UNKNOWN
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub struct KnownCecAudioStatus(u8);

impl KnownCecAudioStatus {
pub fn new(status: u8) -> Option<Self> {
if status == libcec_sys::CEC_AUDIO_VOLUME_STATUS_UNKNOWN as u8 {
None
} else {
Some(KnownCecAudioStatus(status))
}
}

pub fn volume(&self) -> u8 {
self.0 & libcec_sys::CEC_AUDIO_VOLUME_STATUS_MASK as u8
}

pub fn is_muted(&self) -> bool {
self.0 & libcec_sys::CEC_AUDIO_MUTE_STATUS_MASK as u8 != 0
}
}

impl From<KnownCecAudioStatus> for cec_audio_status {
fn from(status: KnownCecAudioStatus) -> Self {
status.into()
}
}

#[cfg(test)]
mod audiostatus_tests {
use super::*;

#[test]
pub fn test_min_volume() {
let status = 0u8;
let wrapper = KnownCecAudioStatus::new(status).unwrap();
assert_eq!(wrapper.volume(), libcec_sys::CEC_AUDIO_VOLUME_MIN as u8);
assert_eq!(wrapper.is_muted(), false);
}

#[test]
pub fn test_max_volume() {
let status = 100u8;
let wrapper = KnownCecAudioStatus::new(status).unwrap();
assert_eq!(wrapper.volume(), libcec_sys::CEC_AUDIO_VOLUME_MAX as u8);
assert_eq!(wrapper.is_muted(), false);
}

#[test]
pub fn test_reserved_volume() {
// This should never happen according to the CEC spec, but we
// don't treat it as an error
let status = 101u8;
let wrapper = KnownCecAudioStatus::new(status).unwrap();
assert_eq!(wrapper.volume(), 101u8);
assert_eq!(wrapper.is_muted(), false);
}

#[test]
pub fn test_muted_at_75() {
let status = 75u8 | libcec_sys::CEC_AUDIO_MUTE_STATUS_MASK as u8;
let wrapper = KnownCecAudioStatus::new(status).unwrap();
assert_eq!(wrapper.volume(), 75u8);
assert_eq!(wrapper.is_muted(), true);
}

#[test]
pub fn test_unknown() {
let status = 0x7Fu8;
let wrapper = KnownCecAudioStatus::new(status);
assert_eq!(wrapper, None);
}
}

/// CecLogicalAddress which does not allow Unknown variant
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub struct KnownCecLogicalAddress(CecLogicalAddress);
Expand Down Expand Up @@ -1212,12 +1286,8 @@ impl CecConnection {
}
}

pub fn audio_get_status(&self) -> CecConnectionResult<()> {
if unsafe { libcec_audio_get_status(self.1) } == 0 {
Err(CecConnectionResultError::TransmitFailed)
} else {
Ok(())
}
pub fn audio_get_status(&self) -> Option<KnownCecAudioStatus> {
KnownCecAudioStatus::new(unsafe { libcec_audio_get_status(self.1) })
}

pub fn set_inactive_view(&self) -> CecConnectionResult<()> {
Expand Down

0 comments on commit 0888e34

Please sign in to comment.