diff --git a/Package.swift b/Package.swift index 7d57ae3..a017eec 100644 --- a/Package.swift +++ b/Package.swift @@ -14,12 +14,5 @@ let package = Package( swiftSettings: [ .define("ENABLE_TCC_SPI") ]) - // linkerSettings: [ - // .unsafeFlags([ - // "-Xlinker", "-sectcreate", - // "-Xlinker", "__TEXT", - // "-Xlinker", "__info_plist", - // "-Xlinker", "Resources/Info.plist", - // ]) ] ) diff --git a/Resources/Info.plist b/Resources/Info.plist deleted file mode 100644 index 90ac6a7..0000000 --- a/Resources/Info.plist +++ /dev/null @@ -1,8 +0,0 @@ - - - - - NSAudioCaptureUsageDescription - This application requires access to system audio to record and stream audio output to external services such as speech recognition APIs. - - diff --git a/Sources/CLI/AudioTee.swift b/Sources/CLI/AudioTee.swift index 394cb3a..7834b3a 100644 --- a/Sources/CLI/AudioTee.swift +++ b/Sources/CLI/AudioTee.swift @@ -118,8 +118,8 @@ struct AudioTee { func run() throws { // Handle permissions mode if permissionsMode { - try handlePermissions() - return + let permissionsHandler = PermissionsHandler(shouldRequest: requestPermissions) + permissionsHandler.handle() // This will exit with appropriate code } // Continue with normal audio tapping functionality @@ -185,44 +185,6 @@ struct AudioTee { recorder.stopRecording() } - private func handlePermissions() throws { - let permissionHandler = AudioRecordingPermission() - - if requestPermissions { - // Request permissions - print("Requesting audio recording permissions...") - print("Initial status: \(permissionHandler.status.rawValue)") - - // Trigger the request - permissionHandler.request() - print("Request method called...") - - // Wait for status to change from unknown with some progress indication - var waitCount = 0 - while permissionHandler.status == .unknown { - // Run the main run loop to allow DispatchQueue.main.async to execute - let result = CFRunLoopRunInMode(CFRunLoopMode.defaultMode, 0.1, true) - if result == CFRunLoopRunResult.stopped || result == CFRunLoopRunResult.finished { - break - } - - waitCount += 1 - if waitCount % 50 == 0 { // Every 5 seconds (50 * 0.1) - print( - "Still waiting for permission response... (status: \(permissionHandler.status.rawValue))" - ) - } - } - - print("Permission status: \(permissionHandler.status.rawValue)") - - } else { - // Just check current permissions - let status = permissionHandler.status - print("Current permission status: \(status.rawValue)") - } - } - private func setupSignalHandlers() { signal(SIGINT) { _ in Logger.info("Received SIGINT, initiating graceful shutdown...") diff --git a/Sources/CLI/PermissionsHandler.swift b/Sources/CLI/PermissionsHandler.swift new file mode 100644 index 0000000..f63fc56 --- /dev/null +++ b/Sources/CLI/PermissionsHandler.swift @@ -0,0 +1,47 @@ +import CoreFoundation +import Foundation + +/// Handles audio recording permissions for the CLI, including checking status and requesting permissions. +/// Uses exit codes to communicate permission status: +/// - 0: granted (authorized) +/// - 1: unknown +/// - 2: denied +struct PermissionsHandler { + private let shouldRequest: Bool + + init(shouldRequest: Bool) { + self.shouldRequest = shouldRequest + } + + /// Handles the permissions workflow and exits with appropriate exit code + func handle() -> Never { + let permissionHandler = AudioRecordingPermission() + + if shouldRequest { + print("Requesting audio recording permissions...") + permissionHandler.request() + + // Wait for the permission request to complete + while permissionHandler.status == .unknown { + // Run the main run loop to allow DispatchQueue.main.async to execute + let result = CFRunLoopRunInMode(CFRunLoopMode.defaultMode, 0.1, true) + if result == CFRunLoopRunResult.stopped || result == CFRunLoopRunResult.finished { + break + } + } + } + + // Get final status and exit with appropriate code + let status = permissionHandler.status + print("Audio recording permission status: \(status.rawValue)") + + switch status { + case .authorized: + exit(0) // granted + case .unknown: + exit(1) // unknown + case .denied: + exit(2) // denied + } + } +}