#import "Permissions.h" #import #import #import bool Permissions::checkScreenCapture() { // macOS 10.15+ requires screen recording permission if (@available(macOS 10.15, *)) { // Use CGPreflightScreenCaptureAccess for reliable permission check // This API is available since macOS 10.15 return CGPreflightScreenCaptureAccess(); } // Before 10.15, no permission needed return true; } void Permissions::requestScreenCapture() { if (@available(macOS 10.15, *)) { // Trigger system permission dialog CGRequestScreenCaptureAccess(); } } bool Permissions::checkAccessibility() { return AXIsProcessTrusted(); } void Permissions::requestAccessibility() { NSDictionary *options = @{ (__bridge id)kAXTrustedCheckOptionPrompt: @YES }; AXIsProcessTrustedWithOptions((__bridge CFDictionaryRef)options); } void Permissions::openScreenCaptureSettings() { if (@available(macOS 10.15, *)) { // Open System Preferences -> Security & Privacy -> Privacy -> Screen Recording NSURL *url = [NSURL URLWithString:@"x-apple.systempreferences:com.apple.preference.security?Privacy_ScreenCapture"]; [[NSWorkspace sharedWorkspace] openURL:url]; } } void Permissions::openAccessibilitySettings() { // Open System Preferences -> Security & Privacy -> Privacy -> Accessibility NSURL *url = [NSURL URLWithString:@"x-apple.systempreferences:com.apple.preference.security?Privacy_Accessibility"]; [[NSWorkspace sharedWorkspace] openURL:url]; } bool Permissions::checkFullDiskAccess() { // There's no official API to check Full Disk Access. // We try to read a protected file that requires FDA permission. // Safari bookmarks is a commonly used test file. NSArray* testPaths = @[ [NSHomeDirectory() stringByAppendingPathComponent:@"Library/Safari/Bookmarks.plist"], [NSHomeDirectory() stringByAppendingPathComponent:@"Library/Safari/CloudTabs.db"], @"/Library/Application Support/com.apple.TCC/TCC.db", [NSHomeDirectory() stringByAppendingPathComponent:@"Library/Application Support/com.apple.TCC/TCC.db"] ]; NSFileManager* fm = [NSFileManager defaultManager]; for (NSString* path in testPaths) { if ([fm fileExistsAtPath:path]) { // File exists, try to read it if ([fm isReadableFileAtPath:path]) { return true; // Can read protected file = FDA granted } else { return false; // File exists but can't read = FDA not granted } } } // If none of the test files exist, assume FDA is granted // (edge case: fresh system without Safari history) return true; } void Permissions::openFullDiskAccessSettings() { // Open System Preferences -> Security & Privacy -> Privacy -> Full Disk Access NSURL *url = [NSURL URLWithString:@"x-apple.systempreferences:com.apple.preference.security?Privacy_AllFiles"]; [[NSWorkspace sharedWorkspace] openURL:url]; } bool Permissions::checkAllPermissions() { return checkScreenCapture() && checkAccessibility() && checkFullDiskAccess(); } bool Permissions::waitForPermissions(int timeoutSeconds) { int elapsed = 0; while (elapsed < timeoutSeconds) { if (checkAllPermissions()) { return true; } [NSThread sleepForTimeInterval:1.0]; elapsed++; } return false; }