Skip to content
Permalink
Browse files
[macOS] Reject getDisplayMedia prompt if system picker times out
https://bugs.webkit.org/show_bug.cgi?id=243679
<rdar://98194903>

Reviewed by Jer Noble.

Set a 60 second timeout when invoking the ScreenCaptureKit system picker, fail capture if
if it fires.

* Source/WebCore/platform/mediastream/mac/ScreenCaptureKitSharingSessionManager.h:
* Source/WebCore/platform/mediastream/mac/ScreenCaptureKitSharingSessionManager.mm:
(WebCore::ScreenCaptureKitSharingSessionManager::pickerCanceledForSession): Clear the
timer. Drive-by: remove the session from the pending list.
(WebCore::ScreenCaptureKitSharingSessionManager::sessionDidEnd): Add logging.
(WebCore::ScreenCaptureKitSharingSessionManager::sessionDidChangeContent): Clear the
timer. Add logging.
(WebCore::ScreenCaptureKitSharingSessionManager::promptForGetDisplayMedia): Set timer,
cancel session if it fires.
(WebCore::ScreenCaptureKitSharingSessionManager::takeSharingSessionForFilter): Add logging.

Canonical link: https://commits.webkit.org/253260@main
  • Loading branch information
eric-carlson committed Aug 9, 2022
1 parent c63d141 commit bbf09215e01bd134a9a834e27bcb9f677928029a
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 0 deletions.
@@ -66,6 +66,7 @@ class ScreenCaptureKitSharingSessionManager : public CanMakeWeakPtr<ScreenCaptur
Vector<RetainPtr<SCContentSharingSession>> m_pendingCaptureSessions;
RetainPtr<WebDisplayMediaPromptHelper> m_promptHelper;
CompletionHandler<void(std::optional<CaptureDevice>)> m_completionHandler;
std::unique_ptr<RunLoop::Timer<ScreenCaptureKitSharingSessionManager>> m_promptWatchdogTimer;
};

} // namespace WebCore
@@ -165,9 +165,18 @@ static bool screenCaptureKitPickerFeatureEnabled()
ASSERT(isMainThread());
ASSERT(m_completionHandler);

RELEASE_LOG(WebRTC, "ScreenCaptureKitSharingSessionManager::pickerCanceledForSession");

m_promptWatchdogTimer = nullptr;
if (!m_completionHandler)
return;

auto index = m_pendingCaptureSessions.findIf([session](auto pendingSession) {
return [pendingSession isEqual:session.get()];
});
if (index != notFound)
m_pendingCaptureSessions.remove(index);

[m_promptHelper stopObservingSession:session.get()];
[session end];

@@ -179,6 +188,8 @@ static bool screenCaptureKitPickerFeatureEnabled()
{
ASSERT(isMainThread());

RELEASE_LOG(WebRTC, "ScreenCaptureKitSharingSessionManager::sessionDidEnd");

[m_promptHelper stopObservingSession:session.get()];

auto index = m_pendingCaptureSessions.findIf([session](auto pendingSession) {
@@ -194,11 +205,15 @@ static bool screenCaptureKitPickerFeatureEnabled()
{
ASSERT(isMainThread());

m_promptWatchdogTimer = nullptr;

if ([session content].type == SCContentFilterTypeNothing) {
sessionDidEnd(session);
return;
}

RELEASE_LOG(WebRTC, "ScreenCaptureKitSharingSessionManager::sessionDidChangeContent");

auto index = m_pendingCaptureSessions.findIf([session](auto pendingSession) {
return [pendingSession isEqual:session.get()];
});
@@ -246,6 +261,8 @@ static bool screenCaptureKitPickerFeatureEnabled()
ASSERT(isAvailable());
ASSERT(!m_completionHandler);

RELEASE_LOG(WebRTC, "ScreenCaptureKitSharingSessionManager::promptForGetDisplayMedia - %s", promptType == PromptType::Window ? "Window" : "Screen");

if (!isAvailable()) {
completionHandler(std::nullopt);
return;
@@ -266,12 +283,24 @@ static bool screenCaptureKitPickerFeatureEnabled()
m_completionHandler = WTFMove(completionHandler);

[session showPickerForType:promptType == PromptType::Window ? SCContentFilterTypeDesktopIndependentWindow : SCContentFilterTypeDisplay];

constexpr Seconds userPromptWatchdogInterval = 60_s;
m_promptWatchdogTimer = makeUnique<RunLoop::Timer<ScreenCaptureKitSharingSessionManager>>(RunLoop::main(), [this, weakThis = WeakPtr { *this }, session = RetainPtr { session }, interval = userPromptWatchdogInterval]() mutable {
if (!weakThis)
return;

RELEASE_LOG_ERROR(WebRTC, "ScreenCaptureKitSharingSessionManager::promptForGetDisplayMedia nothing picked after %f seconds, cancelling.", interval.value());
pickerCanceledForSession(session);
});
m_promptWatchdogTimer->startOneShot(userPromptWatchdogInterval);
}

RetainPtr<SCContentSharingSession> ScreenCaptureKitSharingSessionManager::takeSharingSessionForFilter(SCContentFilter* filter)
{
ASSERT(isMainThread());

RELEASE_LOG(WebRTC, "ScreenCaptureKitSharingSessionManager::takeSharingSessionForFilter");

auto index = m_pendingCaptureSessions.findIf([filter](auto pendingSession) {
return [filter isEqual:[pendingSession content]];
});

0 comments on commit bbf0921

Please sign in to comment.