use oxisound_core::OxiSoundError;
pub use oxisound_core::{AudioSession, SessionCategory, SessionInterruptionEvent};
#[cfg(all(any(target_os = "ios", target_os = "macos"), feature = "avf-audio"))]
mod avf;
pub fn configure_session(category: SessionCategory) -> Result<(), OxiSoundError> {
configure_session_impl(category)
}
pub fn request_microphone_permission() -> Result<bool, OxiSoundError> {
request_microphone_permission_impl()
}
#[cfg(all(any(target_os = "ios", target_os = "macos"), feature = "avf-audio"))]
fn configure_session_impl(category: SessionCategory) -> Result<(), OxiSoundError> {
avf::configure_session(category)
}
#[cfg(all(target_os = "macos", not(feature = "avf-audio")))]
fn configure_session_impl(category: SessionCategory) -> Result<(), OxiSoundError> {
log::debug!(
"configure_session({category:?}): macOS CoreAudio desktop does not require \
AVAudioSession management; returning Ok(()). Enable the `avf-audio` feature \
for Mac Catalyst / iOS targets."
);
Ok(())
}
#[cfg(all(target_os = "ios", not(feature = "avf-audio")))]
fn configure_session_impl(category: SessionCategory) -> Result<(), OxiSoundError> {
let _ = category;
Err(OxiSoundError::UnsupportedConfig(
"configure_session on iOS requires the `avf-audio` feature of oxisound-session".into(),
))
}
#[cfg(not(any(target_os = "macos", target_os = "ios")))]
fn configure_session_impl(category: SessionCategory) -> Result<(), OxiSoundError> {
let _ = category;
Err(OxiSoundError::UnsupportedConfig(
"audio session management is only available on iOS and macOS".into(),
))
}
#[cfg(all(any(target_os = "ios", target_os = "macos"), feature = "avf-audio"))]
fn request_microphone_permission_impl() -> Result<bool, OxiSoundError> {
avf::request_microphone_permission()
}
#[cfg(all(target_os = "macos", not(feature = "avf-audio")))]
fn request_microphone_permission_impl() -> Result<bool, OxiSoundError> {
log::debug!(
"request_microphone_permission: macOS CoreAudio desktop — assumed granted. \
Enable the `avf-audio` feature for TCC permission status checking."
);
Ok(true)
}
#[cfg(all(target_os = "ios", not(feature = "avf-audio")))]
fn request_microphone_permission_impl() -> Result<bool, OxiSoundError> {
Err(OxiSoundError::PermissionDenied(
"request_microphone_permission on iOS requires the `avf-audio` feature of \
oxisound-session"
.into(),
))
}
#[cfg(not(any(target_os = "macos", target_os = "ios")))]
fn request_microphone_permission_impl() -> Result<bool, OxiSoundError> {
Err(OxiSoundError::PermissionDenied(
"microphone permission prompt is not available on this platform".into(),
))
}
#[cfg(test)]
mod tests {
use super::*;
use oxisound_core::SessionCategory;
#[test]
#[cfg(not(any(target_os = "macos", target_os = "ios")))]
fn configure_session_unsupported_on_other_platforms() {
let result = configure_session(SessionCategory::Playback);
assert!(
matches!(result, Err(OxiSoundError::UnsupportedConfig(_))),
"expected UnsupportedConfig, got {result:?}"
);
}
#[test]
#[cfg(not(any(target_os = "macos", target_os = "ios")))]
fn microphone_permission_denied_on_other_platforms() {
let result = request_microphone_permission();
assert!(
matches!(result, Err(OxiSoundError::PermissionDenied(_))),
"expected PermissionDenied, got {result:?}"
);
}
#[test]
#[cfg(all(target_os = "macos", not(feature = "avf-audio")))]
fn configure_session_ok_on_macos_no_avf() {
let result = configure_session(SessionCategory::Playback);
assert!(result.is_ok(), "expected Ok(()), got {result:?}");
}
#[test]
#[cfg(all(target_os = "macos", not(feature = "avf-audio")))]
fn microphone_permission_assumed_granted_on_macos_no_avf() {
let result = request_microphone_permission();
assert!(
matches!(result, Ok(true)),
"expected Ok(true), got {result:?}"
);
}
#[test]
fn configure_session_all_categories_no_panic() {
let categories = [
SessionCategory::Playback,
SessionCategory::Record,
SessionCategory::PlayAndRecord,
SessionCategory::Ambient,
SessionCategory::SoloAmbient,
];
for cat in categories {
let _ = configure_session(cat);
}
}
#[test]
fn request_microphone_permission_no_panic() {
let _ = request_microphone_permission();
}
}