From 2b4610e3af388198b648c0d53b32e334d7260fe5 Mon Sep 17 00:00:00 2001 From: "Cathy J. Fitzpatrick" Date: Sat, 2 Nov 2024 05:42:02 -0700 Subject: [PATCH] fix(macos): prevent indefinite hanging if screen capture is not granted Currently, if Sunshine has not yet been granted the screen capture permission, the program simply hangs indefinitely on startup when it attempts to probe for usable encoders. This is not desirable because it prevents testing and using all of the parts of Sunshine that do not require the screen capture permission. With this patch, the encoder probing will simply fail instead of hanging indefinitely if Sunshine does not yet have the screen capture permission. Note that Sunshine already prints out an error message telling the user that the screen capture permission is needed. The bug is that Sunshine currently indefinitely hangs shortly after printing that message. --- src/platform/macos/display.mm | 8 ++++++++ src/platform/macos/misc.h | 5 +++++ src/platform/macos/misc.mm | 12 ++++++++++++ 3 files changed, 25 insertions(+) diff --git a/src/platform/macos/display.mm b/src/platform/macos/display.mm index 093e8c17f2b..5220c68db72 100644 --- a/src/platform/macos/display.mm +++ b/src/platform/macos/display.mm @@ -5,6 +5,7 @@ #include "src/platform/common.h" #include "src/platform/macos/av_img_t.h" #include "src/platform/macos/av_video.h" +#include "src/platform/macos/misc.h" #include "src/platform/macos/nv12_zero_device.h" #include "src/config.h" @@ -100,6 +101,13 @@ int dummy_img(img_t *img) override { + if (!platf::is_screen_capture_allowed()) { + // If we don't have the screen capture permission, this function will hang + // indefinitely without doing anything useful. Exit instead to avoid this. + // A non-zero return value indicates failure to the calling function. + return 1; + } + auto signal = [av_capture capture:^(CMSampleBufferRef sampleBuffer) { auto new_sample_buffer = std::make_shared(sampleBuffer); auto new_pixel_buffer = std::make_shared(new_sample_buffer->buf); diff --git a/src/platform/macos/misc.h b/src/platform/macos/misc.h index ba0c9507b9b..47d22ed4eca 100644 --- a/src/platform/macos/misc.h +++ b/src/platform/macos/misc.h @@ -8,6 +8,11 @@ #include +namespace platf { + bool + is_screen_capture_allowed(); +} + namespace dyn { typedef void (*apiproc)(); diff --git a/src/platform/macos/misc.mm b/src/platform/macos/misc.mm index 5366fdb238e..cee850dcdf7 100644 --- a/src/platform/macos/misc.mm +++ b/src/platform/macos/misc.mm @@ -42,6 +42,16 @@ CGRequestScreenCaptureAccess(void) __attribute__((weak_import)); #endif + namespace { + auto screen_capture_allowed = std::atomic { false }; + } // namespace + + // Return whether screen capture is allowed for this process. + bool + is_screen_capture_allowed() { + return screen_capture_allowed; + } + std::unique_ptr init() { // This will generate a warning about CGPreflightScreenCaptureAccess and @@ -68,6 +78,8 @@ return nullptr; } #pragma clang diagnostic pop + // Record that we determined that we have the screen capture permission. + screen_capture_allowed = true; return std::make_unique(); }