diff --git a/CMakeLists.txt b/CMakeLists.txt index 1326335df..5c61c1f5e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,11 @@ cmake_minimum_required(VERSION 3.13.0) set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>DLL") -project(sdrangel) +if(APPLE) + project(sdrangel LANGUAGES CXX OBJCXX) +else() + project(sdrangel) +endif() list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/Modules) @@ -911,6 +915,7 @@ target_link_libraries(sdrangelbench sdrbench logging ) + ############ build sdrangel gui ################ if (BUILD_GUI) set(sdrangel_SOURCES @@ -918,7 +923,9 @@ if (BUILD_GUI) sdrgui/resources/sdrangel.rc settings/settings.qrc ) - + if(APPLE) + set(sdrangel_SOURCES ${sdrangel_SOURCES} mac/auth.mm) + endif() if(ANDROID AND NOT ENABLE_QT6) add_library(${CMAKE_PROJECT_NAME} SHARED ${sdrangel_SOURCES}) elseif(ANDROID) @@ -970,7 +977,10 @@ if (BUILD_GUI) sdrbase sdrgui logging - ) +) + endif() + if(APPLE) + target_link_libraries(${CMAKE_PROJECT_NAME} "-framework AVFoundation" objc) endif() if(WIN32) diff --git a/app/main.cpp b/app/main.cpp index cb6a2f310..62d45943c 100644 --- a/app/main.cpp +++ b/app/main.cpp @@ -220,6 +220,12 @@ int main(int argc, char* argv[]) sfc.setVersion(3, 3); sfc.setProfile(QSurfaceFormat::CoreProfile); QSurfaceFormat::setDefaultFormat(sfc); + + // Request authorization for access to camera and microphone (mac/auth.mm) + extern int authCameraAndMic(); + if (authCameraAndMic() < 0) { + qWarning("Failed to authorize access to camera and microphone. Enable access in System Settings > Privacy & Security"); + } #endif #ifdef ANDROID diff --git a/mac/auth.mm b/mac/auth.mm new file mode 100644 index 000000000..f12255706 --- /dev/null +++ b/mac/auth.mm @@ -0,0 +1,35 @@ +// Request permission.authorization to use camera and microphone +// From: https://developer.apple.com/documentation/bundleresources/information_property_list/protected_resources/requesting_authorization_for_media_capture_on_macos?language=objc + +#include + +// Returns: +// 1 - if permission granted, +// 0 - if pending, +// -1 - if not granted. +int authCameraAndMic() +{ + // Request permission to access the camera and microphone. + switch ([AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo]) + { + case AVAuthorizationStatusAuthorized: + // The user has previously granted access to the camera. + return 1; + case AVAuthorizationStatusNotDetermined: + { + // The app hasn't yet asked the user for camera access. + [AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) { + if (granted) { + } + }]; + return 0; + } + case AVAuthorizationStatusDenied: + // The user has previously denied access. + return -1; + case AVAuthorizationStatusRestricted: + // The user can't grant access due to restrictions. + return -1; + } +} +