Ariver
2026-05-18 aa6d716dff8ea05a57500aab74775292df7954b2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
//go:build darwin
 
package permissions
 
/*
#cgo CFLAGS: -x objective-c
#cgo LDFLAGS: -framework ApplicationServices -framework AVFoundation
#include <ApplicationServices/ApplicationServices.h>
#import <AVFoundation/AVFoundation.h>
 
static int accessibilityGranted(void) {
    return AXIsProcessTrusted() ? 1 : 0;
}
 
static void requestAccessibility(void) {
    NSDictionary* opts = @{(__bridge NSString*)kAXTrustedCheckOptionPrompt: @YES};
    AXIsProcessTrustedWithOptions((__bridge CFDictionaryRef)opts);
}
 
static int inputMonitoringGranted(void) {
    return CGPreflightListenEventAccess() ? 1 : 0;
}
 
static void requestInputMonitoring(void) {
    CGRequestListenEventAccess();
}
 
static int microphoneStatus(void) {
    return (int)[AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeAudio];
}
 
static int requestMicrophone(void) {
    __block int granted = 0;
    dispatch_semaphore_t sem = dispatch_semaphore_create(0);
    [AVCaptureDevice requestAccessForMediaType:AVMediaTypeAudio completionHandler:^(BOOL ok) {
        granted = ok ? 1 : 0;
        dispatch_semaphore_signal(sem);
    }];
    dispatch_semaphore_wait(sem, dispatch_time(DISPATCH_TIME_NOW, 30 * NSEC_PER_SEC));
    return granted;
}
*/
import "C"
 
import "os/exec"
 
// Statuses returns the current macOS privacy permission state.
func Statuses() []Status {
    return []Status{
        {
            ID:       IDMicrophone,
            Granted:  C.microphoneStatus() == 3,
            State:    microphoneState(int(C.microphoneStatus())),
            Required: true,
        },
        {
            ID:       IDAccessibility,
            Granted:  C.accessibilityGranted() != 0,
            State:    grantedState(C.accessibilityGranted() != 0),
            Required: true,
        },
        {
            ID:       IDInputMonitoring,
            Granted:  C.inputMonitoringGranted() != 0,
            State:    grantedState(C.inputMonitoringGranted() != 0),
            Required: true,
        },
    }
}
 
// Request asks macOS for a permission where a public prompt API exists,
// then opens the matching System Settings pane.
func Request(id string) {
    switch id {
    case IDMicrophone:
        C.requestMicrophone()
        openSettings(id)
    case IDAccessibility:
        C.requestAccessibility()
        openSettings(id)
    case IDInputMonitoring:
        C.requestInputMonitoring()
        openSettings(id)
    }
}
 
func OpenSettings(id string) {
    openSettings(id)
}
 
func microphoneState(status int) string {
    switch status {
    case 0:
        return "notDetermined"
    case 1:
        return "restricted"
    case 2:
        return "denied"
    case 3:
        return "granted"
    default:
        return "unknown"
    }
}
 
func grantedState(granted bool) string {
    if granted {
        return "granted"
    }
    return "denied"
}
 
func openSettings(id string) {
    url := "x-apple.systempreferences:com.apple.preference.security"
    switch id {
    case IDMicrophone:
        url = "x-apple.systempreferences:com.apple.preference.security?Privacy_Microphone"
    case IDAccessibility:
        url = "x-apple.systempreferences:com.apple.preference.security?Privacy_Accessibility"
    case IDInputMonitoring:
        url = "x-apple.systempreferences:com.apple.preference.security?Privacy_ListenEvent"
    }
    _ = exec.Command("open", url).Start()
}