Skip to content
This repository was archived by the owner on Apr 28, 2026. It is now read-only.

Commit cf718cb

Browse files
Simplify microphone permission to AVCaptureDevice only
The dual AVAudioApplication + AVCaptureDevice combination logic was causing false denials when the two APIs disagreed. Philo uses AVCaptureDevice alone and it works reliably. Drop the AVAudioApplication layer entirely. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent f369c8b commit cf718cb

1 file changed

Lines changed: 4 additions & 99 deletions

File tree

src-tauri/swift-permissions/src/lib.swift

Lines changed: 4 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -27,56 +27,13 @@ private func mapCaptureMicrophoneStatus(_ status: AVAuthorizationStatus) -> Int
2727
}
2828
}
2929

30-
@available(macOS 14.0, *)
31-
private func mapAudioApplicationPermission(_ permission: AVAudioApplication.recordPermission) -> Int {
32-
switch permission {
33-
case .granted:
34-
grantedValue
35-
case .undetermined:
36-
neverRequestedValue
37-
case .denied:
38-
deniedValue
39-
@unknown default:
40-
errorValue
41-
}
42-
}
43-
44-
private func captureMicrophonePermissionStatus() -> Int {
30+
@_cdecl("_microphone_permission_status")
31+
public func _microphone_permission_status() -> Int {
4532
mapCaptureMicrophoneStatus(AVCaptureDevice.authorizationStatus(for: .audio))
4633
}
4734

48-
private func combinedMicrophonePermissionStatus(appStatus: Int, captureStatus: Int) -> Int {
49-
if appStatus == grantedValue || captureStatus == grantedValue {
50-
return grantedValue
51-
}
52-
53-
if appStatus == errorValue {
54-
return captureStatus
55-
}
56-
57-
if captureStatus == errorValue {
58-
return appStatus
59-
}
60-
61-
if appStatus == deniedValue || captureStatus == deniedValue {
62-
return deniedValue
63-
}
64-
65-
return neverRequestedValue
66-
}
67-
68-
private func currentMicrophonePermissionStatus() -> Int {
69-
let captureStatus = captureMicrophonePermissionStatus()
70-
71-
if #available(macOS 14.0, *) {
72-
let appStatus = mapAudioApplicationPermission(AVAudioApplication.shared.recordPermission)
73-
return combinedMicrophonePermissionStatus(appStatus: appStatus, captureStatus: captureStatus)
74-
}
75-
76-
return captureStatus
77-
}
78-
79-
private func requestCaptureMicrophonePermission() -> Bool {
35+
@_cdecl("_request_microphone_permission")
36+
public func _request_microphone_permission() -> Bool {
8037
let status = AVCaptureDevice.authorizationStatus(for: .audio)
8138

8239
switch status {
@@ -100,58 +57,6 @@ private func requestCaptureMicrophonePermission() -> Bool {
10057
}
10158
}
10259

103-
@available(macOS 14.0, *)
104-
private func requestAppMicrophonePermission() -> Bool {
105-
switch AVAudioApplication.shared.recordPermission {
106-
case .granted:
107-
return true
108-
case .denied:
109-
return false
110-
case .undetermined:
111-
let semaphore = DispatchSemaphore(value: 0)
112-
var granted = false
113-
114-
AVAudioApplication.requestRecordPermission { allowed in
115-
granted = allowed
116-
semaphore.signal()
117-
}
118-
119-
_ = semaphore.wait(timeout: .now() + .seconds(60))
120-
return granted
121-
@unknown default:
122-
return false
123-
}
124-
}
125-
126-
@_cdecl("_microphone_permission_status")
127-
public func _microphone_permission_status() -> Int {
128-
currentMicrophonePermissionStatus()
129-
}
130-
131-
@_cdecl("_request_microphone_permission")
132-
public func _request_microphone_permission() -> Bool {
133-
if currentMicrophonePermissionStatus() == grantedValue {
134-
return true
135-
}
136-
137-
if #available(macOS 14.0, *) {
138-
let appStatus = mapAudioApplicationPermission(AVAudioApplication.shared.recordPermission)
139-
if appStatus == neverRequestedValue && requestAppMicrophonePermission() {
140-
return true
141-
}
142-
143-
if currentMicrophonePermissionStatus() == grantedValue {
144-
return true
145-
}
146-
}
147-
148-
if requestCaptureMicrophonePermission() {
149-
return true
150-
}
151-
152-
return currentMicrophonePermissionStatus() == grantedValue
153-
}
154-
15560
@_cdecl("_audio_capture_permission_status")
15661
public func _audio_capture_permission_status() -> Int {
15762
guard let tccHandle,

0 commit comments

Comments
 (0)