Title: [289696] trunk/Source
Revision
289696
Author
[email protected]
Date
2022-02-12 08:08:49 -0800 (Sat, 12 Feb 2022)

Log Message

[macOS] Use system window and screen picker when available
https://bugs.webkit.org/show_bug.cgi?id=236531
rdar://87111816

Reviewed by Jer Noble.

Source/WebCore:

Tested manually.

* SourcesCocoa.txt: Add new files.
* WebCore.xcodeproj/project.pbxproj: Ditto.

* en.lproj/Localizable.strings: Update prompts.

* platform/mediastream/cocoa/DisplayCaptureSourceCocoa.cpp:
(WebCore::DisplayCaptureSourceCocoa::capturerConfigurationChanged): Allow a capturer
to notify the source of a configuration change.
* platform/mediastream/cocoa/DisplayCaptureSourceCocoa.h:
(WebCore::CapturerObserver::capturerConfigurationChanged):

* platform/mediastream/mac/ScreenCaptureKitCaptureSource.h:
* platform/mediastream/mac/ScreenCaptureKitCaptureSource.mm:
(-[WebCoreScreenCaptureKitHelper stream:didStopWithError:]): Forward delegate callbacks
to the capture source.
(-[WebCoreScreenCaptureKitHelper sessionDidEnd:]): Ditto.
(-[WebCoreScreenCaptureKitHelper sessionDidChangeContent:]): Ditto.
(-[WebCoreScreenCaptureKitHelper pickerCanceledForSession:]): Ditto.
(WebCore::ScreenCaptureKitCaptureSource::sessionDidChangeContent): React to a
reconfiguration.
(WebCore::ScreenCaptureKitCaptureSource::sessionDidEnd):
(WebCore::ScreenCaptureKitCaptureSource::startContentStream): Use the sharing
session manager when available.
(WebCore::ScreenCaptureKitCaptureSource::intrinsicSize const): Get the size from
the content when possible.

* platform/mediastream/mac/ScreenCaptureKitSharingSessionManager.h: Added.
(WebCore::ScreenCaptureKitSharingSessionManager::SharingSessionObserver::operator== const):
* platform/mediastream/mac/ScreenCaptureKitSharingSessionManager.mm: Added.
(-[WebDisplayMediaPromptHelper initWithCallback:]):
(-[WebDisplayMediaPromptHelper disconnect]):
(-[WebDisplayMediaPromptHelper startObservingSession:]):
(-[WebDisplayMediaPromptHelper stopObservingSession:]):
(-[WebDisplayMediaPromptHelper sessionDidEnd:]):
(-[WebDisplayMediaPromptHelper sessionDidChangeContent:]):
(-[WebDisplayMediaPromptHelper pickerCanceledForSession:]):
(WebCore::ScreenCaptureKitSharingSessionManager::isAvailable):
(WebCore::ScreenCaptureKitSharingSessionManager::singleton):
(WebCore::ScreenCaptureKitSharingSessionManager::ScreenCaptureKitSharingSessionManager):
(WebCore::ScreenCaptureKitSharingSessionManager::~ScreenCaptureKitSharingSessionManager):
(WebCore::ScreenCaptureKitSharingSessionManager::pickerCanceledForSession):
(WebCore::ScreenCaptureKitSharingSessionManager::sessionDidEnd):
(WebCore::ScreenCaptureKitSharingSessionManager::sessionDidChangeContent):
(WebCore::ScreenCaptureKitSharingSessionManager::showWindowPicker):
(WebCore::ScreenCaptureKitSharingSessionManager::showScreenPicker):
(WebCore::ScreenCaptureKitSharingSessionManager::promptForGetDisplayMedia):
(WebCore::ScreenCaptureKitSharingSessionManager::takeSharingSessionForFilter):

Source/WebCore/PAL:

* PAL.xcodeproj/project.pbxproj:
* pal/mac/ScreenCaptureKitSoftLink.h:
* pal/mac/ScreenCaptureKitSoftLink.mm:
* pal/spi/mac/ScreenCaptureKitSPI.h: Added.

Source/WebKit:

* Platform/spi/Cocoa/SafeBrowsingSPI.h:
* UIProcess/mac/DisplayCaptureSessionManager.mm:
(WebKit::DisplayCaptureSessionManager::alertForGetDisplayMedia): Update prompt strings.
(WebKit::DisplayCaptureSessionManager::showWindowPicker): Use capture session
manager when available.
(WebKit::DisplayCaptureSessionManager::showScreenPicker): Ditto.

Source/WTF:

* wtf/PlatformHave.h: Define HAVE_SC_CONTENT_SHARING_SESSION.

Modified Paths

Added Paths

Diff

Modified: trunk/Source/WTF/ChangeLog (289695 => 289696)


--- trunk/Source/WTF/ChangeLog	2022-02-12 15:48:00 UTC (rev 289695)
+++ trunk/Source/WTF/ChangeLog	2022-02-12 16:08:49 UTC (rev 289696)
@@ -1,3 +1,13 @@
+2022-02-12  Eric Carlson  <[email protected]>
+
+        [macOS] Use system window and screen picker when available
+        https://bugs.webkit.org/show_bug.cgi?id=236531
+        rdar://87111816
+
+        Reviewed by Jer Noble.
+
+        * wtf/PlatformHave.h: Define HAVE_SC_CONTENT_SHARING_SESSION.
+
 2022-02-11  Nikolaos Mouchtaris  <[email protected]>
 
         Turn overscroll-behavior on by default

Modified: trunk/Source/WTF/wtf/PlatformHave.h (289695 => 289696)


--- trunk/Source/WTF/wtf/PlatformHave.h	2022-02-12 15:48:00 UTC (rev 289695)
+++ trunk/Source/WTF/wtf/PlatformHave.h	2022-02-12 16:08:49 UTC (rev 289696)
@@ -1146,6 +1146,10 @@
 #define HAVE_SCREEN_CAPTURE_KIT 1
 #endif
 
+#if (PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 130000)
+#define HAVE_SC_CONTENT_SHARING_SESSION 1
+#endif
+
 #if ((PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 130000) \
     || (PLATFORM(IOS) && __IPHONE_OS_VERSION_MIN_REQUIRED >= 160000))
 #define HAVE_SANDBOX_STATE_FLAGS 1

Modified: trunk/Source/WebCore/ChangeLog (289695 => 289696)


--- trunk/Source/WebCore/ChangeLog	2022-02-12 15:48:00 UTC (rev 289695)
+++ trunk/Source/WebCore/ChangeLog	2022-02-12 16:08:49 UTC (rev 289696)
@@ -1,3 +1,61 @@
+2022-02-12  Eric Carlson  <[email protected]>
+
+        [macOS] Use system window and screen picker when available
+        https://bugs.webkit.org/show_bug.cgi?id=236531
+        rdar://87111816
+
+        Reviewed by Jer Noble.
+
+        Tested manually.
+
+        * SourcesCocoa.txt: Add new files.
+        * WebCore.xcodeproj/project.pbxproj: Ditto.
+
+        * en.lproj/Localizable.strings: Update prompts.
+
+        * platform/mediastream/cocoa/DisplayCaptureSourceCocoa.cpp:
+        (WebCore::DisplayCaptureSourceCocoa::capturerConfigurationChanged): Allow a capturer
+        to notify the source of a configuration change.
+        * platform/mediastream/cocoa/DisplayCaptureSourceCocoa.h:
+        (WebCore::CapturerObserver::capturerConfigurationChanged):
+
+        * platform/mediastream/mac/ScreenCaptureKitCaptureSource.h:
+        * platform/mediastream/mac/ScreenCaptureKitCaptureSource.mm:
+        (-[WebCoreScreenCaptureKitHelper stream:didStopWithError:]): Forward delegate callbacks
+        to the capture source.
+        (-[WebCoreScreenCaptureKitHelper sessionDidEnd:]): Ditto.
+        (-[WebCoreScreenCaptureKitHelper sessionDidChangeContent:]): Ditto.
+        (-[WebCoreScreenCaptureKitHelper pickerCanceledForSession:]): Ditto.
+        (WebCore::ScreenCaptureKitCaptureSource::sessionDidChangeContent): React to a
+        reconfiguration.
+        (WebCore::ScreenCaptureKitCaptureSource::sessionDidEnd):
+        (WebCore::ScreenCaptureKitCaptureSource::startContentStream): Use the sharing
+        session manager when available.
+        (WebCore::ScreenCaptureKitCaptureSource::intrinsicSize const): Get the size from
+        the content when possible.
+
+        * platform/mediastream/mac/ScreenCaptureKitSharingSessionManager.h: Added.
+        (WebCore::ScreenCaptureKitSharingSessionManager::SharingSessionObserver::operator== const):
+        * platform/mediastream/mac/ScreenCaptureKitSharingSessionManager.mm: Added.
+        (-[WebDisplayMediaPromptHelper initWithCallback:]):
+        (-[WebDisplayMediaPromptHelper disconnect]):
+        (-[WebDisplayMediaPromptHelper startObservingSession:]):
+        (-[WebDisplayMediaPromptHelper stopObservingSession:]):
+        (-[WebDisplayMediaPromptHelper sessionDidEnd:]):
+        (-[WebDisplayMediaPromptHelper sessionDidChangeContent:]):
+        (-[WebDisplayMediaPromptHelper pickerCanceledForSession:]):
+        (WebCore::ScreenCaptureKitSharingSessionManager::isAvailable):
+        (WebCore::ScreenCaptureKitSharingSessionManager::singleton):
+        (WebCore::ScreenCaptureKitSharingSessionManager::ScreenCaptureKitSharingSessionManager):
+        (WebCore::ScreenCaptureKitSharingSessionManager::~ScreenCaptureKitSharingSessionManager):
+        (WebCore::ScreenCaptureKitSharingSessionManager::pickerCanceledForSession):
+        (WebCore::ScreenCaptureKitSharingSessionManager::sessionDidEnd):
+        (WebCore::ScreenCaptureKitSharingSessionManager::sessionDidChangeContent):
+        (WebCore::ScreenCaptureKitSharingSessionManager::showWindowPicker):
+        (WebCore::ScreenCaptureKitSharingSessionManager::showScreenPicker):
+        (WebCore::ScreenCaptureKitSharingSessionManager::promptForGetDisplayMedia):
+        (WebCore::ScreenCaptureKitSharingSessionManager::takeSharingSessionForFilter):
+
 2022-02-12  Rob Buis  <[email protected]>
 
         Suppress style invalidation when matching :checked

Modified: trunk/Source/WebCore/PAL/ChangeLog (289695 => 289696)


--- trunk/Source/WebCore/PAL/ChangeLog	2022-02-12 15:48:00 UTC (rev 289695)
+++ trunk/Source/WebCore/PAL/ChangeLog	2022-02-12 16:08:49 UTC (rev 289696)
@@ -1,3 +1,16 @@
+2022-02-12  Eric Carlson  <[email protected]>
+
+        [macOS] Use system window and screen picker when available
+        https://bugs.webkit.org/show_bug.cgi?id=236531
+        rdar://87111816
+
+        Reviewed by Jer Noble.
+
+        * PAL.xcodeproj/project.pbxproj:
+        * pal/mac/ScreenCaptureKitSoftLink.h:
+        * pal/mac/ScreenCaptureKitSoftLink.mm:
+        * pal/spi/mac/ScreenCaptureKitSPI.h: Added.
+
 2022-02-10  Eric Carlson  <[email protected]>
 
         [macOS] Support both versions of ScreenCaptureKit API

Modified: trunk/Source/WebCore/PAL/PAL.xcodeproj/project.pbxproj (289695 => 289696)


--- trunk/Source/WebCore/PAL/PAL.xcodeproj/project.pbxproj	2022-02-12 15:48:00 UTC (rev 289695)
+++ trunk/Source/WebCore/PAL/PAL.xcodeproj/project.pbxproj	2022-02-12 16:08:49 UTC (rev 289696)
@@ -21,6 +21,7 @@
 /* End PBXAggregateTarget section */
 
 /* Begin PBXBuildFile section */
+		07035D3127A9B33000FB03E4 /* ScreenCaptureKitSPI.h in Headers */ = {isa = PBXBuildFile; fileRef = 07035D3027A9B32E00FB03E4 /* ScreenCaptureKitSPI.h */; };
 		071C00372707EDF000D027C7 /* ReplayKitSoftLink.mm in Sources */ = {isa = PBXBuildFile; fileRef = 071C00352707EDF000D027C7 /* ReplayKitSoftLink.mm */; };
 		071C00382707EDF000D027C7 /* ReplayKitSoftLink.h in Headers */ = {isa = PBXBuildFile; fileRef = 071C00362707EDF000D027C7 /* ReplayKitSoftLink.h */; };
 		07611DB6243FA5BF00D80704 /* UsageTrackingSoftLink.h in Headers */ = {isa = PBXBuildFile; fileRef = 07611DB4243FA5BE00D80704 /* UsageTrackingSoftLink.h */; };
@@ -430,6 +431,7 @@
 /* End PBXCopyFilesBuildPhase section */
 
 /* Begin PBXFileReference section */
+		07035D3027A9B32E00FB03E4 /* ScreenCaptureKitSPI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScreenCaptureKitSPI.h; sourceTree = "<group>"; };
 		071C00352707EDF000D027C7 /* ReplayKitSoftLink.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ReplayKitSoftLink.mm; sourceTree = "<group>"; };
 		071C00362707EDF000D027C7 /* ReplayKitSoftLink.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ReplayKitSoftLink.h; sourceTree = "<group>"; };
 		07611DB4243FA5BE00D80704 /* UsageTrackingSoftLink.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UsageTrackingSoftLink.h; sourceTree = "<group>"; };
@@ -1055,7 +1057,7 @@
 				0C7785841F45130F00F4EBB6 /* NSWindowSPI.h */,
 				0C7785851F45130F00F4EBB6 /* PIPSPI.h */,
 				0C7785871F45130F00F4EBB6 /* QuickLookMacSPI.h */,
-				A1175B481F6AFF8E00C4B9F0 /* SpeechSynthesisSPI.h */,
+				07035D3027A9B32E00FB03E4 /* ScreenCaptureKitSPI.h */,
 				71B1141F26823ACD004D6701 /* SystemPreviewSPI.h */,
 				0C7785881F45130F00F4EBB6 /* TelephonyUtilitiesSPI.h */,
 			);
@@ -1677,6 +1679,7 @@
 				442956CD218A72DF0080DB54 /* RevealSPI.h in Headers */,
 				BC4DDD9F273EF56E00660EBB /* SceneKitSPI.h in Headers */,
 				07789182273B14FF00E408D1 /* ScreenCaptureKitSoftLink.h in Headers */,
+				07035D3127A9B33000FB03E4 /* ScreenCaptureKitSPI.h in Headers */,
 				570AB8F120AE2E8D00B8BE87 /* SecKeyProxySPI.h in Headers */,
 				0C2DA1581F3BEB4900DBC317 /* ServersSPI.h in Headers */,
 				A3C66CDD1F462D6A009E6EE9 /* SessionID.h in Headers */,

Modified: trunk/Source/WebCore/PAL/pal/mac/ScreenCaptureKitSoftLink.h (289695 => 289696)


--- trunk/Source/WebCore/PAL/pal/mac/ScreenCaptureKitSoftLink.h	2022-02-12 15:48:00 UTC (rev 289695)
+++ trunk/Source/WebCore/PAL/pal/mac/ScreenCaptureKitSoftLink.h	2022-02-12 16:08:49 UTC (rev 289696)
@@ -36,6 +36,7 @@
 SOFT_LINK_CLASS_FOR_HEADER_WITH_AVAILABILITY(PAL, SCContentFilter, API_AVAILABLE(macos(12.3)))
 SOFT_LINK_CLASS_FOR_HEADER_WITH_AVAILABILITY(PAL, SCStreamConfiguration, API_AVAILABLE(macos(12.3)))
 SOFT_LINK_CLASS_FOR_HEADER_WITH_AVAILABILITY(PAL, SCStream, API_AVAILABLE(macos(12.3)))
+SOFT_LINK_CLASS_FOR_HEADER(PAL, SCContentSharingSession)
 
 SOFT_LINK_CONSTANT_MAY_FAIL_FOR_HEADER(PAL, ScreenCaptureKit, SCStreamFrameInfoStatus, NSString *)
 #define SCStreamFrameInfoStatus get_ScreenCaptureKit_SCStreamFrameInfoStatus()

Modified: trunk/Source/WebCore/PAL/pal/mac/ScreenCaptureKitSoftLink.mm (289695 => 289696)


--- trunk/Source/WebCore/PAL/pal/mac/ScreenCaptureKitSoftLink.mm	2022-02-12 15:48:00 UTC (rev 289695)
+++ trunk/Source/WebCore/PAL/pal/mac/ScreenCaptureKitSoftLink.mm	2022-02-12 16:08:49 UTC (rev 289696)
@@ -36,6 +36,7 @@
 SOFT_LINK_CLASS_FOR_SOURCE_OPTIONAL_WITH_EXPORT_AND_AVAILABILITY(PAL, ScreenCaptureKit, SCContentFilter, PAL_EXPORT, API_AVAILABLE(macos(12.3)))
 SOFT_LINK_CLASS_FOR_SOURCE_OPTIONAL_WITH_EXPORT_AND_AVAILABILITY(PAL, ScreenCaptureKit, SCStreamConfiguration, PAL_EXPORT, API_AVAILABLE(macos(12.3)))
 SOFT_LINK_CLASS_FOR_SOURCE_OPTIONAL_WITH_EXPORT_AND_AVAILABILITY(PAL, ScreenCaptureKit, SCStream, PAL_EXPORT, API_AVAILABLE(macos(12.3)))
+SOFT_LINK_CLASS_FOR_SOURCE_OPTIONAL_WITH_EXPORT(PAL, ScreenCaptureKit, SCContentSharingSession, PAL_EXPORT)
 
 SOFT_LINK_CONSTANT_MAY_FAIL_FOR_SOURCE_WITH_EXPORT(PAL, ScreenCaptureKit, SCStreamFrameInfoStatus, NSString *, PAL_EXPORT)
 SOFT_LINK_CONSTANT_MAY_FAIL_FOR_SOURCE_WITH_EXPORT(PAL, ScreenCaptureKit, SCStreamFrameInfoStatusKey, NSString *, PAL_EXPORT)

Added: trunk/Source/WebCore/PAL/pal/spi/mac/ScreenCaptureKitSPI.h (0 => 289696)


--- trunk/Source/WebCore/PAL/pal/spi/mac/ScreenCaptureKitSPI.h	                        (rev 0)
+++ trunk/Source/WebCore/PAL/pal/spi/mac/ScreenCaptureKitSPI.h	2022-02-12 16:08:49 UTC (rev 289696)
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2022 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#if HAVE(SCREEN_CAPTURE_KIT)
+
+#import <ScreenCaptureKit/ScreenCaptureKit.h>
+
+#if USE(APPLE_INTERNAL_SDK)
+
+#import <ScreenCaptureKit/SCContentFilterPrivate.h>
+#import <ScreenCaptureKit/SCContentSharingSession.h>
+#import <ScreenCaptureKit/SCStream_Private.h>
+
+#else // USE(APPLE_INTERNAL_SDK)
+
+NS_ASSUME_NONNULL_BEGIN
+
+typedef NS_ENUM(NSInteger, SCContentFilterType) {
+    SCContentFilterTypeNothing,
+    SCContentFilterTypeDisplay,
+    SCContentFilterTypeAppsAndWindowsPinnedToDisplay,
+    SCContentFilterTypeDesktopIndependentWindow,
+    SCContentFilterTypeClientShouldImplementDefault
+};
+
+@interface SCContentFilter ()
+@property (nonatomic, strong) SCWindow *window;
+@property (nonatomic, strong) SCDisplay *display;
+@property (nonatomic, assign) SCContentFilterType type;
+@end
+
+@interface SCContentFilterDisplayInformation : NSObject
+@property (nonatomic, readonly) SCDisplay *display;
+@end
+
+@interface SCContentFilterDesktopIndependentWindowInformation : NSObject
+@property (nonatomic, readonly) SCWindow *window;
+@end
+
+@class SCContentSharingSession;
+
+@protocol SCContentSharingSessionProtocol <NSObject>
+@optional
+- (void)sessionDidEnd:(SCContentSharingSession *)session;
+- (void)sessionDidChangeContent:(SCContentSharingSession *)session;
+- (void)pickerCanceledForSession:(SCContentSharingSession *)session;
+@end
+
+@interface SCContentSharingSession : NSObject
+@property (nonatomic, weak) id<SCContentSharingSessionProtocol> delegate;
+@property (nonatomic, readonly, copy) SCContentFilter *content;
+
+- (instancetype)init NS_UNAVAILABLE;
+- (instancetype)initWithTitle:(NSString *)title;
+- (BOOL)isEqualToSharingSession:(SCContentSharingSession *)other;
+- (void)showPickerForType:(SCContentFilterType)type;
+- (void)updateContent:(SCContentFilter *)content;
+- (void)end;
+@end
+
+@interface SCStream (SCContentSharing) <SCContentSharingSessionProtocol>
+- (instancetype)initWithSharingSession:(SCContentSharingSession *)session captureOutputProperties:(SCStreamConfiguration *)streamConfig delegate:(id<SCStreamDelegate>)delegate;
+@end
+
+NS_ASSUME_NONNULL_END
+
+#endif // USE(APPLE_INTERNAL_SDK)
+
+#endif // HAVE(SCREEN_CAPTURE_KIT)

Modified: trunk/Source/WebCore/SourcesCocoa.txt (289695 => 289696)


--- trunk/Source/WebCore/SourcesCocoa.txt	2022-02-12 15:48:00 UTC (rev 289695)
+++ trunk/Source/WebCore/SourcesCocoa.txt	2022-02-12 16:08:49 UTC (rev 289696)
@@ -565,6 +565,7 @@
 platform/mediastream/mac/RealtimeOutgoingAudioSourceCocoa.cpp
 platform/mediastream/mac/RealtimeOutgoingVideoSourceCocoa.cpp
 platform/mediastream/mac/ScreenCaptureKitCaptureSource.mm
+platform/mediastream/mac/ScreenCaptureKitSharingSessionManager.mm
 platform/mediastream/mac/WebAudioSourceProviderCocoa.mm
 platform/mock/MediaPlaybackTargetMock.cpp
 platform/mock/MediaPlaybackTargetPickerMock.cpp

Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (289695 => 289696)


--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2022-02-12 15:48:00 UTC (rev 289695)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2022-02-12 16:08:49 UTC (rev 289696)
@@ -118,6 +118,7 @@
 		073794FA19F5864E00E5A045 /* RTCDataChannelHandlerMock.h in Headers */ = {isa = PBXBuildFile; fileRef = 073794F419F5864E00E5A045 /* RTCDataChannelHandlerMock.h */; };
 		073794FE19F5864E00E5A045 /* RTCNotifiersMock.h in Headers */ = {isa = PBXBuildFile; fileRef = 073794F819F5864E00E5A045 /* RTCNotifiersMock.h */; };
 		0738E5EC2499839000DA101C /* AVOutputDeviceMenuControllerTargetPicker.mm in Sources */ = {isa = PBXBuildFile; fileRef = 0738E5EA249968AD00DA101C /* AVOutputDeviceMenuControllerTargetPicker.mm */; };
+		073955BB27AB277F009A08D2 /* ScreenCaptureKitSharingSessionManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 07035D3227A9B60B00FB03E4 /* ScreenCaptureKitSharingSessionManager.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		073A15542177A42600EA08F2 /* RemoteVideoSample.h in Headers */ = {isa = PBXBuildFile; fileRef = 073A15532177A39A00EA08F2 /* RemoteVideoSample.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		073B87671E4385AC0071C0EC /* AudioSampleBufferList.h in Headers */ = {isa = PBXBuildFile; fileRef = 073B87631E43859D0071C0EC /* AudioSampleBufferList.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		073B87691E4385AC0071C0EC /* AudioSampleDataSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 073B87651E43859D0071C0EC /* AudioSampleDataSource.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -5926,6 +5927,8 @@
 		070334D61459FFD5008D8D45 /* TrackBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TrackBase.h; sourceTree = "<group>"; };
 		070334D8145A006F008D8D45 /* TrackBase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TrackBase.cpp; sourceTree = "<group>"; };
 		070334E8145A1F35008D8D45 /* JSTrackCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSTrackCustom.cpp; sourceTree = "<group>"; };
+		07035D3227A9B60B00FB03E4 /* ScreenCaptureKitSharingSessionManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ScreenCaptureKitSharingSessionManager.h; sourceTree = "<group>"; };
+		07035D3427A9B61100FB03E4 /* ScreenCaptureKitSharingSessionManager.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = ScreenCaptureKitSharingSessionManager.mm; sourceTree = "<group>"; };
 		070363DA181A1CDC00C074A5 /* AVCaptureDeviceManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AVCaptureDeviceManager.h; sourceTree = "<group>"; };
 		070363DB181A1CDC00C074A5 /* AVCaptureDeviceManager.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = AVCaptureDeviceManager.mm; sourceTree = "<group>"; };
 		070363DE181A1CDC00C074A5 /* AVVideoCaptureSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AVVideoCaptureSource.h; sourceTree = "<group>"; };
@@ -18730,6 +18733,8 @@
 				41D1938F2152C561006F14CA /* RealtimeVideoUtilities.h */,
 				070BED97273F415600583926 /* ScreenCaptureKitCaptureSource.h */,
 				070BED96273F415600583926 /* ScreenCaptureKitCaptureSource.mm */,
+				07035D3227A9B60B00FB03E4 /* ScreenCaptureKitSharingSessionManager.h */,
+				07035D3427A9B61100FB03E4 /* ScreenCaptureKitSharingSessionManager.mm */,
 				07D6373E1BB0B11300256CE9 /* WebAudioSourceProviderCocoa.h */,
 				07D6373F1BB0B11300256CE9 /* WebAudioSourceProviderCocoa.mm */,
 			);
@@ -37071,6 +37076,7 @@
 				7B7311FB25C092B7003B2796 /* ScopedHighPerformanceGPURequest.h in Headers */,
 				BCEC01BE0C274DAC009F4EC9 /* Screen.h in Headers */,
 				070BED98273F415D00583926 /* ScreenCaptureKitCaptureSource.h in Headers */,
+				073955BB27AB277F009A08D2 /* ScreenCaptureKitSharingSessionManager.h in Headers */,
 				C1E1D236203DF15400584665 /* ScreenProperties.h in Headers */,
 				A84D82C111D3474800972990 /* ScriptableDocumentParser.h in Headers */,
 				462E4C502616A811003A2C67 /* ScriptBuffer.h in Headers */,

Modified: trunk/Source/WebCore/en.lproj/Localizable.strings (289695 => 289696)


--- trunk/Source/WebCore/en.lproj/Localizable.strings	2022-02-12 15:48:00 UTC (rev 289695)
+++ trunk/Source/WebCore/en.lproj/Localizable.strings	2022-02-12 16:08:49 UTC (rev 289696)
@@ -146,10 +146,10 @@
 "Align Right (Undo action name)" = "Align Right";
 
 /* Allow screen button title in window and screen sharing prompt */
-"Allow Observing a Screen" = "Allow Observing a Screen";
+"Allow to Share Screen" = "Allow to Share Screen";
 
 /* Allow window button title in window and screen sharing prompt */
-"Allow Observing a Window" = "Allow Observing a Window";
+"Allow to Share Window" = "Allow to Share Window";
 
 /* Button title in Storage Access API prompt */
 "Allow (cross-site cookie and website data access)" = "Allow";

Modified: trunk/Source/WebCore/platform/mediastream/cocoa/DisplayCaptureSourceCocoa.cpp (289695 => 289696)


--- trunk/Source/WebCore/platform/mediastream/cocoa/DisplayCaptureSourceCocoa.cpp	2022-02-12 15:48:00 UTC (rev 289695)
+++ trunk/Source/WebCore/platform/mediastream/cocoa/DisplayCaptureSourceCocoa.cpp	2022-02-12 16:08:49 UTC (rev 289696)
@@ -324,6 +324,16 @@
     videoSampleAvailable(*sample.get(), metadata);
 }
 
+void DisplayCaptureSourceCocoa::capturerConfigurationChanged()
+{
+    m_currentSettings = { };
+    auto capturerIntrinsicSize = m_capturer->intrinsicSize();
+    if (this->intrinsicSize() != capturerIntrinsicSize) {
+        m_capabilities = { };
+        setIntrinsicSize(capturerIntrinsicSize);
+    }
+}
+
 void DisplayCaptureSourceCocoa::setLogger(const Logger& logger, const void* identifier)
 {
     RealtimeMediaSource::setLogger(logger, identifier);

Modified: trunk/Source/WebCore/platform/mediastream/cocoa/DisplayCaptureSourceCocoa.h (289695 => 289696)


--- trunk/Source/WebCore/platform/mediastream/cocoa/DisplayCaptureSourceCocoa.h	2022-02-12 15:48:00 UTC (rev 289695)
+++ trunk/Source/WebCore/platform/mediastream/cocoa/DisplayCaptureSourceCocoa.h	2022-02-12 16:08:49 UTC (rev 289696)
@@ -57,6 +57,7 @@
 
     virtual void capturerIsRunningChanged(bool) { }
     virtual void capturerFailed() { };
+    virtual void capturerConfigurationChanged() { };
 };
 
 class DisplayCaptureSourceCocoa final
@@ -99,6 +100,11 @@
             if (m_observer)
                 m_observer->capturerFailed();
         }
+        void configurationChanged()
+        {
+            if (m_observer)
+                m_observer->capturerConfigurationChanged();
+        }
 
     private:
         WeakPtr<CapturerObserver> m_observer;
@@ -132,6 +138,7 @@
     // CapturerObserver
     void capturerIsRunningChanged(bool isRunning) final { notifyMutedChange(!isRunning); }
     void capturerFailed() final { captureFailed(); }
+    void capturerConfigurationChanged() final;
 
     void emitFrame();
 

Modified: trunk/Source/WebCore/platform/mediastream/mac/ScreenCaptureKitCaptureSource.h (289695 => 289696)


--- trunk/Source/WebCore/platform/mediastream/mac/ScreenCaptureKitCaptureSource.h	2022-02-12 15:48:00 UTC (rev 289695)
+++ trunk/Source/WebCore/platform/mediastream/mac/ScreenCaptureKitCaptureSource.h	2022-02-12 16:08:49 UTC (rev 289696)
@@ -39,13 +39,12 @@
 OBJC_CLASS SCShareableContent;
 OBJC_CLASS SCStream;
 OBJC_CLASS SCContentFilter;
+OBJC_CLASS SCContentSharingSession;
 OBJC_CLASS SCStreamConfiguration;
 OBJC_CLASS SCWindow;
 OBJC_CLASS WebCoreScreenCaptureKitHelper;
 using CMSampleBufferRef = struct opaqueCMSampleBuffer*;
 
-typedef struct __IOSurface* IOSurfaceRef;
-
 namespace WebCore {
 
 class ScreenCaptureKitCaptureSource final
@@ -70,6 +69,8 @@
     void streamFailedWithError(RetainPtr<NSError>&&, const String&);
     enum class SampleType { Video };
     void streamDidOutputSampleBuffer(RetainPtr<CMSampleBufferRef>, SampleType);
+    void sessionDidChangeContent(RetainPtr<SCContentSharingSession>);
+    void sessionDidEnd(RetainPtr<SCContentSharingSession>);
 
 private:
 
@@ -104,6 +105,7 @@
     RetainPtr<SCContentFilter> m_contentFilter;
     RetainPtr<SCStream> m_contentStream;
     RetainPtr<SCStreamConfiguration> m_streamConfiguration;
+    RetainPtr<SCContentSharingSession> m_contentSharingSession;
     OSObjectPtr<dispatch_queue_t> m_captureQueue;
     BlockPtr<void(SCStream *, CMSampleBufferRef)> m_frameAvailableHandler;
     CaptureDevice m_captureDevice;

Modified: trunk/Source/WebCore/platform/mediastream/mac/ScreenCaptureKitCaptureSource.mm (289695 => 289696)


--- trunk/Source/WebCore/platform/mediastream/mac/ScreenCaptureKitCaptureSource.mm	2022-02-12 15:48:00 UTC (rev 289695)
+++ trunk/Source/WebCore/platform/mediastream/mac/ScreenCaptureKitCaptureSource.mm	2022-02-12 16:08:49 UTC (rev 289696)
@@ -23,8 +23,8 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#include "config.h"
-#include "ScreenCaptureKitCaptureSource.h"
+#import "config.h"
+#import "ScreenCaptureKitCaptureSource.h"
 
 #if HAVE(SCREEN_CAPTURE_KIT)
 
@@ -34,7 +34,9 @@
 #import "PlatformScreen.h"
 #import "RealtimeMediaSourceCenter.h"
 #import "RealtimeVideoUtilities.h"
+#import "ScreenCaptureKitSharingSessionManager.h"
 #import <ScreenCaptureKit/ScreenCaptureKit.h>
+#import <pal/spi/mac/ScreenCaptureKitSPI.h>
 #import <wtf/BlockObjCExceptions.h>
 #import <wtf/BlockPtr.h>
 #import <wtf/NeverDestroyed.h>
@@ -91,7 +93,11 @@
 #pragma clang diagnostic ignored "-Wunguarded-availability-new"
 
 using namespace WebCore;
-@interface WebCoreScreenCaptureKitHelper : NSObject<SCStreamDelegate, WKSCStreamOutput> {
+@interface WebCoreScreenCaptureKitHelper : NSObject<SCStreamDelegate,
+#if HAVE(SC_CONTENT_SHARING_SESSION)
+    SCContentSharingSessionProtocol,
+#endif
+    WKSCStreamOutput> {
     WeakPtr<ScreenCaptureKitCaptureSource> _callback;
 }
 
@@ -99,6 +105,9 @@
 - (void)disconnect;
 - (void)stream:(SCStream *)stream didStopWithError:(NSError *)error;
 - (void)stream:(SCStream *)stream didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer ofType:(WKSCStreamOutputType)type;
+- (void)sessionDidEnd:(SCContentSharingSession *)session;
+- (void)sessionDidChangeContent:(SCContentSharingSession *)session;
+- (void)pickerCanceledForSession:(SCContentSharingSession *)session;
 @end
 
 @implementation WebCoreScreenCaptureKitHelper
@@ -119,11 +128,11 @@
 
 - (void)stream:(SCStream *)stream didStopWithError:(NSError *)error
 {
-    callOnMainRunLoop([strongSelf = RetainPtr { self }, error = RetainPtr { error }]() mutable {
-        if (!strongSelf->_callback)
+    callOnMainRunLoop([self, strongSelf = RetainPtr { self }, error = RetainPtr { error }]() mutable {
+        if (!_callback)
             return;
 
-        strongSelf->_callback->streamFailedWithError(WTFMove(error), "-[SCStreamDelegate stream:didStopWithError:] called"_s);
+        _callback->streamFailedWithError(WTFMove(error), "-[SCStreamDelegate stream:didStopWithError:] called"_s);
     });
 }
 
@@ -137,6 +146,25 @@
     });
 }
 
+- (void)sessionDidEnd:(SCContentSharingSession *)session
+{
+    RunLoop::main().dispatch([self, strongSelf = RetainPtr { self }, session = RetainPtr { session }]() mutable {
+        if (_callback)
+            _callback->sessionDidEnd(session);
+    });
+}
+
+- (void)sessionDidChangeContent:(SCContentSharingSession *)session
+{
+    RunLoop::main().dispatch([self, strongSelf = RetainPtr { self }, session = RetainPtr { session }]() mutable {
+        if (_callback)
+            _callback->sessionDidChangeContent(session);
+    });
+}
+
+- (void)pickerCanceledForSession:(SCContentSharingSession *)session
+{
+}
 @end
 
 #pragma clang diagnostic pop
@@ -236,6 +264,45 @@
     captureFailed();
 }
 
+void ScreenCaptureKitCaptureSource::sessionDidChangeContent(RetainPtr<SCContentSharingSession> session)
+{
+    ASSERT(isMainThread());
+
+    if ([session content].type == SCContentFilterTypeNothing)
+        return;
+
+    std::optional<CaptureDevice> device;
+    SCContentFilter* content = [session content];
+    switch (content.type) {
+    case SCContentFilterTypeDesktopIndependentWindow:
+        device = windowCaptureDeviceWithPersistentID(String::number(content.desktopIndependentWindowInfo.window.windowID));
+        m_content = content.desktopIndependentWindowInfo.window;
+        break;
+    case SCContentFilterTypeDisplay:
+        device = screenCaptureDeviceWithPersistentID(String::number(content.displayInfo.display.displayID));
+        m_content = content.displayInfo.display;
+        break;
+    case SCContentFilterTypeNothing:
+    case SCContentFilterTypeAppsAndWindowsPinnedToDisplay:
+    case SCContentFilterTypeClientShouldImplementDefault:
+        ASSERT_NOT_REACHED();
+        return;
+    }
+    if (!device) {
+        streamFailedWithError(nil, "Failed find CaptureDevice after content change"_s);
+        return;
+    }
+
+    m_captureDevice = device.value();
+    m_intrinsicSize = { };
+    configurationChanged();
+}
+
+void ScreenCaptureKitCaptureSource::sessionDidEnd(RetainPtr<SCContentSharingSession>)
+{
+    streamFailedWithError(nil, "sessionDidEnd"_s);
+}
+
 DisplayCaptureSourceCocoa::DisplayFrameType ScreenCaptureKitCaptureSource::generateFrame()
 {
     return m_currentFrame;
@@ -348,8 +415,22 @@
     else
         m_contentStream = adoptNS([PAL::allocSCStreamInstance() initWithFilter:m_contentFilter.get() captureOutputProperties:streamConfiguration().get() delegate:m_captureHelper.get()]);
 
+#if HAVE(SC_CONTENT_SHARING_SESSION)
+    if (ScreenCaptureKitSharingSessionManager::isAvailable()) {
+        m_contentSharingSession = ScreenCaptureKitSharingSessionManager::singleton().takeSharingSessionForFilter(m_contentFilter.get());
+        if (!m_contentSharingSession) {
+            streamFailedWithError(nil, "Failed to get SharingSession"_s);
+            return;
+        }
+
+        m_contentStream = adoptNS([PAL::allocSCStreamInstance() initWithSharingSession:m_contentSharingSession.get() captureOutputProperties:streamConfiguration().get() delegate:m_captureHelper.get()]);
+    } else
+#endif
+        m_contentStream = adoptNS([PAL::allocSCStreamInstance() initWithFilter:m_contentFilter.get() captureOutputProperties:streamConfiguration().get() delegate:m_captureHelper.get()]);
+
+
     if (!m_contentStream) {
-        streamFailedWithError(nil, "Failed to allocate SLContentStream"_s);
+        streamFailedWithError(nil, "Failed to allocate ContentStream"_s);
         return;
     }
 
@@ -385,6 +466,19 @@
     if (m_intrinsicSize)
         return m_intrinsicSize.value();
 
+    if (m_content) {
+        auto frame = switchOn(m_content.value(),
+            [] (const RetainPtr<SCDisplay> display) -> CGRect {
+                return [display frame];
+            },
+            [] (const RetainPtr<SCWindow> window) -> CGRect {
+                return [window frame];
+            }
+        );
+
+        return { static_cast<int>(frame.size.width), static_cast<int>(frame.size.height) };
+    }
+
     if (m_captureDevice.type() == CaptureDevice::DeviceType::Screen) {
         auto displayMode = adoptCF(CGDisplayCopyDisplayMode(m_deviceID));
         auto screenWidth = CGDisplayModeGetPixelsWide(displayMode.get());

Added: trunk/Source/WebCore/platform/mediastream/mac/ScreenCaptureKitSharingSessionManager.h (0 => 289696)


--- trunk/Source/WebCore/platform/mediastream/mac/ScreenCaptureKitSharingSessionManager.h	                        (rev 0)
+++ trunk/Source/WebCore/platform/mediastream/mac/ScreenCaptureKitSharingSessionManager.h	2022-02-12 16:08:49 UTC (rev 289696)
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2022 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#pragma once
+
+#if HAVE(SC_CONTENT_SHARING_SESSION)
+
+#include <wtf/RetainPtr.h>
+#include <wtf/Vector.h>
+#include <wtf/WeakPtr.h>
+
+OBJC_CLASS SCContentSharingSession;
+OBJC_CLASS WebDisplayMediaPromptHelper;
+
+namespace WebCore {
+
+class CaptureDevice;
+
+class ScreenCaptureKitSharingSessionManager : public CanMakeWeakPtr<ScreenCaptureKitSharingSessionManager> {
+public:
+    class SharingSessionObserver : public CanMakeWeakPtr<SharingSessionObserver> {
+    public:
+        virtual ~SharingSessionObserver() = default;
+
+        enum class Type { Screen, Window };
+        virtual Type sessionType() const = 0;
+        virtual uint32_t sessionID() const = 0;
+
+        virtual void sessionChanged() = 0;
+        virtual void sessionEnded() = 0;
+
+        bool operator==(const SharingSessionObserver& other) const
+        {
+            return sessionType() == other.sessionType() && sessionID() == other.sessionID();
+        }
+    };
+
+    WEBCORE_EXPORT static ScreenCaptureKitSharingSessionManager& singleton();
+    WEBCORE_EXPORT static bool isAvailable();
+
+    ScreenCaptureKitSharingSessionManager();
+    ~ScreenCaptureKitSharingSessionManager();
+
+    RetainPtr<SCContentSharingSession> takeSharingSessionForFilter(SCContentFilter*);
+
+    RetainPtr<SCContentSharingSession> addSharingSessionObserver(SharingSessionObserver&);
+    void removeSharingSessionObserver(SharingSessionObserver&);
+
+    void sessionDidChangeContent(RetainPtr<SCContentSharingSession>);
+    void pickerCanceledForSession(RetainPtr<SCContentSharingSession>);
+    void sessionDidEnd(RetainPtr<SCContentSharingSession>);
+
+    WEBCORE_EXPORT void showWindowPicker(CompletionHandler<void(std::optional<CaptureDevice>)>&&);
+    WEBCORE_EXPORT void showScreenPicker(CompletionHandler<void(std::optional<CaptureDevice>)>&&);
+
+private:
+    void cleanupAllSessions();
+
+    enum class PromptType { Window, Screen };
+    void promptForGetDisplayMedia(PromptType, CompletionHandler<void(std::optional<CaptureDevice>)>&&);
+
+    Vector<RetainPtr<SCContentSharingSession>> m_pendingCaptureSessions;
+    RetainPtr<WebDisplayMediaPromptHelper> m_promptHelper;
+    CompletionHandler<void(std::optional<CaptureDevice>)> m_completionHandler;
+};
+
+} // namespace WebCore
+
+#endif // HAVE(SC_CONTENT_SHARING_SESSION)

Added: trunk/Source/WebCore/platform/mediastream/mac/ScreenCaptureKitSharingSessionManager.mm (0 => 289696)


--- trunk/Source/WebCore/platform/mediastream/mac/ScreenCaptureKitSharingSessionManager.mm	                        (rev 0)
+++ trunk/Source/WebCore/platform/mediastream/mac/ScreenCaptureKitSharingSessionManager.mm	2022-02-12 16:08:49 UTC (rev 289696)
@@ -0,0 +1,273 @@
+/*
+ * Copyright (C) 2022 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "config.h"
+#import "ScreenCaptureKitSharingSessionManager.h"
+
+#if HAVE(SC_CONTENT_SHARING_SESSION)
+
+#import "Logging.h"
+#import "ScreenCaptureKitCaptureSource.h"
+#import <pal/spi/mac/ScreenCaptureKitSPI.h>
+#import <wtf/cocoa/Entitlements.h>
+
+#import <pal/mac/ScreenCaptureKitSoftLink.h>
+
+using namespace WebCore;
+
+@interface WebDisplayMediaPromptHelper : NSObject <SCContentSharingSessionProtocol> {
+    WeakPtr<ScreenCaptureKitSharingSessionManager> _callback;
+    Vector<RetainPtr<SCContentSharingSession>> _sessions;
+}
+
+- (instancetype)initWithCallback:(ScreenCaptureKitSharingSessionManager*)callback;
+- (void)disconnect;
+- (void)startObservingSession:(SCContentSharingSession *)session;
+- (void)stopObservingSession:(SCContentSharingSession *)session;
+- (void)sessionDidEnd:(SCContentSharingSession *)session;
+- (void)sessionDidChangeContent:(SCContentSharingSession *)session;
+- (void)pickerCanceledForSession:(SCContentSharingSession *)session;
+@end
+
+@implementation WebDisplayMediaPromptHelper
+- (instancetype)initWithCallback:(ScreenCaptureKitSharingSessionManager*)callback
+{
+    self = [super init];
+    if (!self)
+        return self;
+
+    _callback = WeakPtr { callback };
+    return self;
+}
+
+- (void)disconnect
+{
+    _callback = nullptr;
+    for (auto& session : _sessions)
+        [session setDelegate:nil];
+    _sessions.clear();
+}
+
+- (void)startObservingSession:(SCContentSharingSession *)session
+{
+    ASSERT(!_sessions.contains(session));
+    _sessions.append(RetainPtr { session });
+    [session setDelegate:self];
+}
+
+- (void)stopObservingSession:(SCContentSharingSession *)session
+{
+    auto index = _sessions.find(RetainPtr { session });
+    if (index == notFound)
+        return;
+
+    [session setDelegate:nil];
+    _sessions.removeAll(session);
+}
+
+- (void)sessionDidEnd:(SCContentSharingSession *)session
+{
+    auto index = _sessions.find(RetainPtr { session });
+    if (index == notFound)
+        return;
+}
+
+- (void)sessionDidChangeContent:(SCContentSharingSession *)session
+{
+    RunLoop::main().dispatch([self, protectedSelf = RetainPtr { self }, session = RetainPtr { session }]() mutable {
+        if (_callback)
+            _callback->sessionDidChangeContent(session);
+    });
+}
+
+- (void)pickerCanceledForSession:(SCContentSharingSession *)session
+{
+    RunLoop::main().dispatch([self, protectedSelf = RetainPtr { self }, session = RetainPtr { session }]() mutable {
+        if (_callback)
+            _callback->pickerCanceledForSession(session);
+    });
+}
+@end
+
+namespace WebCore {
+
+bool ScreenCaptureKitSharingSessionManager::isAvailable()
+{
+    return WTF::processHasEntitlement("com.apple.private.screencapturekit.sharingsession")
+            && PAL::getSCContentSharingSessionClass()
+            && ScreenCaptureKitCaptureSource::isAvailable();
+}
+
+ScreenCaptureKitSharingSessionManager& ScreenCaptureKitSharingSessionManager::singleton()
+{
+    ASSERT(isMainThread());
+    static NeverDestroyed<ScreenCaptureKitSharingSessionManager> manager;
+    return manager;
+}
+
+ScreenCaptureKitSharingSessionManager::ScreenCaptureKitSharingSessionManager()
+{
+}
+
+ScreenCaptureKitSharingSessionManager::~ScreenCaptureKitSharingSessionManager()
+{
+    if (m_promptHelper) {
+        [m_promptHelper disconnect];
+        m_promptHelper = nullptr;
+    }
+
+    for (auto session : m_pendingCaptureSessions) {
+        [m_promptHelper stopObservingSession:session.get()];
+        [session end];
+    }
+    m_pendingCaptureSessions.clear();
+}
+
+void ScreenCaptureKitSharingSessionManager::pickerCanceledForSession(RetainPtr<SCContentSharingSession> session)
+{
+    ASSERT(isMainThread());
+    ASSERT(m_completionHandler);
+
+    if (!m_completionHandler)
+        return;
+
+    [m_promptHelper stopObservingSession:session.get()];
+    [session end];
+
+    auto completionHandler = std::exchange(m_completionHandler, { });
+    completionHandler(std::nullopt);
+}
+
+void ScreenCaptureKitSharingSessionManager::sessionDidEnd(RetainPtr<SCContentSharingSession> session)
+{
+    ASSERT(isMainThread());
+
+    auto index = m_pendingCaptureSessions.findIf([session](auto pendingSession) {
+        return [pendingSession isEqual:session.get()];
+    });
+    if (index == notFound)
+        return;
+
+    [m_promptHelper stopObservingSession:session.get()];
+    m_pendingCaptureSessions.remove(index);
+}
+
+void ScreenCaptureKitSharingSessionManager::sessionDidChangeContent(RetainPtr<SCContentSharingSession> session)
+{
+    ASSERT(isMainThread());
+
+    if ([session content].type == SCContentFilterTypeNothing) {
+        sessionDidEnd(session);
+        return;
+    }
+
+    auto index = m_pendingCaptureSessions.findIf([session](auto pendingSession) {
+        return [pendingSession isEqual:session.get()];
+    });
+    if (index == notFound)
+        return;
+
+    ASSERT(m_completionHandler);
+    if (!m_completionHandler)
+        return;
+
+    std::optional<CaptureDevice> device;
+    SCContentFilter* content = [session content];
+    switch (content.type) {
+    case SCContentFilterTypeDesktopIndependentWindow:
+        device = ScreenCaptureKitCaptureSource::windowCaptureDeviceWithPersistentID(String::number(content.desktopIndependentWindowInfo.window.windowID));
+        break;
+    case SCContentFilterTypeDisplay:
+        device = ScreenCaptureKitCaptureSource::screenCaptureDeviceWithPersistentID(String::number(content.displayInfo.display.displayID));
+        break;
+    case SCContentFilterTypeNothing:
+    case SCContentFilterTypeAppsAndWindowsPinnedToDisplay:
+    case SCContentFilterTypeClientShouldImplementDefault:
+        ASSERT_NOT_REACHED();
+        return;
+    }
+
+    auto completionHandler = std::exchange(m_completionHandler, { });
+    completionHandler(device);
+}
+
+void ScreenCaptureKitSharingSessionManager::showWindowPicker(CompletionHandler<void(std::optional<CaptureDevice>)>&& completionHandler)
+{
+    promptForGetDisplayMedia(PromptType::Window, WTFMove(completionHandler));
+}
+
+void ScreenCaptureKitSharingSessionManager::showScreenPicker(CompletionHandler<void(std::optional<CaptureDevice>)>&& completionHandler)
+{
+    promptForGetDisplayMedia(PromptType::Screen, WTFMove(completionHandler));
+}
+
+void ScreenCaptureKitSharingSessionManager::promptForGetDisplayMedia(PromptType promptType, CompletionHandler<void(std::optional<CaptureDevice>)>&& completionHandler)
+{
+    ASSERT(isAvailable());
+    ASSERT(!m_completionHandler);
+
+    if (!isAvailable() || m_completionHandler)
+        return;
+
+    SCContentSharingSession* session = [[PAL::getSCContentSharingSessionClass() alloc] initWithTitle:@"WebKit getDisplayMedia Prompt"];
+    if (!session) {
+        RELEASE_LOG_ERROR(WebRTC, "ScreenCaptureKitSharingSessionManager::promptForGetDisplayMedia unable to create sharing session");
+        completionHandler(std::nullopt);
+        return;
+    }
+
+    if (!m_promptHelper)
+        m_promptHelper = adoptNS([[WebDisplayMediaPromptHelper alloc] initWithCallback:this]);
+
+    [m_promptHelper startObservingSession:session];
+    m_pendingCaptureSessions.append(session);
+    m_completionHandler = WTFMove(completionHandler);
+
+    [session showPickerForType:promptType == PromptType::Window ? SCContentFilterTypeDesktopIndependentWindow : SCContentFilterTypeDisplay];
+}
+
+RetainPtr<SCContentSharingSession> ScreenCaptureKitSharingSessionManager::takeSharingSessionForFilter(SCContentFilter* filter)
+{
+    ASSERT(isMainThread());
+
+    auto index = m_pendingCaptureSessions.findIf([filter](auto pendingSession) {
+        return [filter isEqual:[pendingSession content]];
+    });
+    ASSERT(index != notFound);
+    if (index == notFound) {
+        RELEASE_LOG_ERROR(WebRTC, "ScreenCaptureKitSharingSessionManager::takeSharingSessionForFilter sharing session not found");
+        return nullptr;
+    }
+
+    RetainPtr<SCContentSharingSession> session = m_pendingCaptureSessions[index];
+    m_pendingCaptureSessions.remove(index);
+
+    return WTFMove(session);
+}
+
+
+} // namespace WebCore
+
+#endif // HAVE(SC_CONTENT_SHARING_SESSION)

Modified: trunk/Source/WebKit/ChangeLog (289695 => 289696)


--- trunk/Source/WebKit/ChangeLog	2022-02-12 15:48:00 UTC (rev 289695)
+++ trunk/Source/WebKit/ChangeLog	2022-02-12 16:08:49 UTC (rev 289696)
@@ -1,3 +1,18 @@
+2022-02-12  Eric Carlson  <[email protected]>
+
+        [macOS] Use system window and screen picker when available
+        https://bugs.webkit.org/show_bug.cgi?id=236531
+        rdar://87111816
+
+        Reviewed by Jer Noble.
+
+        * Platform/spi/Cocoa/SafeBrowsingSPI.h:
+        * UIProcess/mac/DisplayCaptureSessionManager.mm:
+        (WebKit::DisplayCaptureSessionManager::alertForGetDisplayMedia): Update prompt strings.
+        (WebKit::DisplayCaptureSessionManager::showWindowPicker): Use capture session 
+        manager when available.
+        (WebKit::DisplayCaptureSessionManager::showScreenPicker): Ditto.
+
 2022-02-12  Kevin Turner  <[email protected]>
 
         Invoke mouse hover delegate callback on iOS

Modified: trunk/Source/WebKit/Platform/spi/Cocoa/SafeBrowsingSPI.h (289695 => 289696)


--- trunk/Source/WebKit/Platform/spi/Cocoa/SafeBrowsingSPI.h	2022-02-12 15:48:00 UTC (rev 289695)
+++ trunk/Source/WebKit/Platform/spi/Cocoa/SafeBrowsingSPI.h	2022-02-12 16:08:49 UTC (rev 289696)
@@ -27,7 +27,7 @@
 
 #import <Foundation/Foundation.h>
 
-#if USE(APPLE_INTERNAL_SDK)
+#if 0 && USE(APPLE_INTERNAL_SDK)
 
 #import <SafariSafeBrowsing/SafariSafeBrowsing.h>
 

Modified: trunk/Source/WebKit/UIProcess/mac/DisplayCaptureSessionManager.mm (289695 => 289696)


--- trunk/Source/WebKit/UIProcess/mac/DisplayCaptureSessionManager.mm	2022-02-12 15:48:00 UTC (rev 289695)
+++ trunk/Source/WebKit/UIProcess/mac/DisplayCaptureSessionManager.mm	2022-02-12 16:08:49 UTC (rev 289696)
@@ -36,6 +36,7 @@
 #import <WebCore/LocalizedStrings.h>
 #import <WebCore/MockRealtimeMediaSourceCenter.h>
 #import <WebCore/ScreenCaptureKitCaptureSource.h>
+#import <WebCore/ScreenCaptureKitSharingSessionManager.h>
 #import <WebCore/SecurityOriginData.h>
 #import <wtf/BlockPtr.h>
 #import <wtf/MainThread.h>
@@ -141,8 +142,8 @@
         visibleOrigin = applicationVisibleName();
 
     NSString *alertTitle = [NSString stringWithFormat:WEB_UI_NSSTRING(@"Allow “%@” to observe one of your windows or screens?", "Message for window and screen sharing prompt"), visibleOrigin];
-    auto *allowWindowButtonString = WEB_UI_NSSTRING(@"Allow Observing a Window", "Allow window button title in window and screen sharing prompt");
-    auto *allowScreenButtonString = WEB_UI_NSSTRING(@"Allow Observing a Screen", "Allow screen button title in window and screen sharing prompt");
+    auto *allowWindowButtonString = WEB_UI_NSSTRING(@"Allow to Share Window", "Allow window button title in window and screen sharing prompt");
+    auto *allowScreenButtonString = WEB_UI_NSSTRING(@"Allow to Share Screen", "Allow screen button title in window and screen sharing prompt");
     auto *doNotAllowButtonString = WEB_UI_NSSTRING(@"Don’t Allow (window and screen sharing)", "Disallow button title in window and screen sharing prompt");
 
     auto alert = adoptNS([[NSAlert alloc] init]);
@@ -198,6 +199,13 @@
         return;
     }
 
+#if HAVE(SC_CONTENT_SHARING_SESSION)
+    if (ScreenCaptureKitSharingSessionManager::isAvailable()) {
+        ScreenCaptureKitSharingSessionManager::singleton().showWindowPicker(WTFMove(completionHandler));
+        return;
+    }
+#endif
+
     alertForWindowSelection(page, origin, [completionHandler = WTFMove(completionHandler)] (std::optional<String> windowID, std::optional<String> windowTitle) mutable {
 
         if (!windowID || !windowTitle) {
@@ -217,6 +225,13 @@
         return;
     }
 
+#if HAVE(SC_CONTENT_SHARING_SESSION)
+    if (ScreenCaptureKitSharingSessionManager::isAvailable()) {
+        ScreenCaptureKitSharingSessionManager::singleton().showScreenPicker(WTFMove(completionHandler));
+        return;
+    }
+#endif
+
     callOnMainRunLoop([completionHandler = WTFMove(completionHandler)] () mutable {
         for (auto& device : RealtimeMediaSourceCenter::singleton().displayCaptureFactory().displayCaptureDeviceManager().captureDevices()) {
             if (device.enabled() && device.type() == CaptureDevice::DeviceType::Screen) {
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to