#![cfg(test)]
#![allow(
clippy::unwrap_used,
clippy::expect_used,
clippy::print_stderr,
clippy::panic,
reason = "unit tests"
)]
use windows::Win32::System::Com::{COINIT_MULTITHREADED, CoInitializeEx};
use super::{
PROCESS_LOOPBACK_CHANNELS, PROCESS_LOOPBACK_RATE, open_process_loopback_client,
process_loopback_mode,
};
use crate::CaptureError;
use crate::windows_audio::{ComGuard, HARDWARE_TEST_LOCK, WasapiProcessTreeScope};
use windows::Win32::Media::Audio::{
PROCESS_LOOPBACK_MODE_EXCLUDE_TARGET_PROCESS_TREE,
PROCESS_LOOPBACK_MODE_INCLUDE_TARGET_PROCESS_TREE,
};
const AUDCLNT_E_INVALID_STREAM_FLAG: i32 = 0x8889_0021_u32.cast_signed();
#[test]
fn include_children_selects_the_include_target_process_tree_mode() {
assert_eq!(
process_loopback_mode(WasapiProcessTreeScope::IncludeChildren),
PROCESS_LOOPBACK_MODE_INCLUDE_TARGET_PROCESS_TREE
);
}
#[test]
fn exclude_process_tree_selects_the_exclude_target_process_tree_mode() {
assert_eq!(
process_loopback_mode(WasapiProcessTreeScope::ExcludeProcessTree),
PROCESS_LOOPBACK_MODE_EXCLUDE_TARGET_PROCESS_TREE
);
}
#[test]
fn process_loopback_opens_for_this_process() {
let _guard = HARDWARE_TEST_LOCK
.lock()
.unwrap_or_else(std::sync::PoisonError::into_inner);
let hr = unsafe { CoInitializeEx(None, COINIT_MULTITHREADED) };
assert!(hr.is_ok(), "CoInitializeEx failed: {hr:?}");
let _com = ComGuard;
match open_process_loopback_client(std::process::id(), WasapiProcessTreeScope::IncludeChildren)
{
Ok((client, _capture, rate, channels)) => {
assert_eq!(rate, PROCESS_LOOPBACK_RATE);
assert_eq!(channels, PROCESS_LOOPBACK_CHANNELS);
let _ = unsafe { client.Stop() };
}
Err(CaptureError::BackendCode { code }) => {
assert_ne!(
code, AUDCLNT_E_INVALID_STREAM_FLAG,
"Initialize rejected our stream flags (AUDCLNT_E_INVALID_STREAM_FLAG): \
process loopback needs AUDCLNT_STREAMFLAGS_LOOPBACK and rejects the \
sample-rate-conversion flags"
);
eprintln!(
"skipping: this machine has no process-loopback support ({code:#010x}); \
the stream-flag assertion above still held"
);
}
Err(other) => panic!("process loopback failed without a native code: {other}"),
}
}