diff --git a/packaging/macos/Info.plist.in b/packaging/macos/Info.plist.in index 78958249e..e9d9dc3bc 100644 --- a/packaging/macos/Info.plist.in +++ b/packaging/macos/Info.plist.in @@ -42,6 +42,10 @@ NSRequiresAquaSystemAppearance + + NSMicrophoneUsageDescription + FilmCraft uses the microphone to record voice-over onto the timeline. NSHumanReadableCopyright Copyright © the FilmCraft authors. MIT OR Apache-2.0. diff --git a/packaging/macos/entitlements.plist b/packaging/macos/entitlements.plist index 79fa2237b..74540670f 100644 --- a/packaging/macos/entitlements.plist +++ b/packaging/macos/entitlements.plist @@ -1,9 +1,13 @@ - + + com.apple.security.device.audio-input + diff --git a/xtask/src/main.rs b/xtask/src/main.rs index 631678d84..648f217b0 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -504,3 +504,24 @@ fn main() -> ExitCode { } } } + +#[cfg(test)] +mod tests { + use std::path::Path; + + fn macos_packaging(file: &str) -> String { + let path = Path::new(env!("CARGO_MANIFEST_DIR")).join("../packaging/macos").join(file); + std::fs::read_to_string(&path).unwrap_or_else(|e| panic!("{}: {e}", path.display())) + } + + /// Voice-over recording needs both halves on macOS: the usage string (else the permission + /// prompt never appears) and the hardened-runtime audio-input entitlement (else the input is + /// blocked). Regression test for #659. + #[test] + fn macos_bundle_may_use_the_microphone() { + let plist = macos_packaging("Info.plist.in"); + assert!(plist.contains("NSMicrophoneUsageDescription")); + let entitlements = macos_packaging("entitlements.plist"); + assert!(entitlements.contains("com.apple.security.device.audio-input\n ")); + } +}