From 102e44942cedce1660ffbcd693259447c63be61a Mon Sep 17 00:00:00 2001 From: Eric Carlson Date: Mon, 31 Oct 2022 11:26:12 -0700 Subject: [PATCH] Cherry-pick 0ee91ab89adb. rdar://problem/100335624 Use an ephemeral device ID for the Continuity camera when it is not the system preferred https://bugs.webkit.org/show_bug.cgi?id=247208 rdar://100335624 Reviewed by Jer Noble. A "Continuity Camera", an iPhone used as a camera for a Macintosh, is listed as an AVCaptureDevice whenever it is in close enough to the Macintosh to be used, but it is only the "system preferred camera" when it is in an appropriate position and orientation to be used as a camera for the device. This means that a script may remember the device ID when a user has set up the phone to be used as a camera, and then pass it to getUserMedia later when the phone is near the Macintosh but not usable as a camera - e.g. in the user's pocket. To prevent this problem, use a device ID that is only valid for the lifetime of the current frame when a Continuity Camera is available but is not the system preferred camera. * LayoutTests/http/tests/media/media-stream/enumerate-devices-ephemeral-id-expected.txt: Added. * LayoutTests/http/tests/media/media-stream/enumerate-devices-ephemeral-id.html: Added. * LayoutTests/http/tests/media/media-stream/resources/enumerate-devices-ephemeral-id-iframe.html: Added. * Source/WTF/wtf/PlatformHave.h: Define HAVE_CONTINUITY_CAMEARA * Source/WebCore/Modules/mediastream/CanvasCaptureMediaStreamTrack.cpp: (WebCore::CanvasCaptureMediaStreamTrack::Source::Source): Update for RealtimeMediaSource constructor changes. * Source/WebCore/Modules/mediastream/MediaDevices.cpp: (WebCore::MediaDevices::exposeDevices): Take a MediaDeviceHashSalts instead of a String because there are now two hash salts. (WebCore::MediaDevices::enumerateDevices): Ditto. * Source/WebCore/Modules/mediastream/MediaDevices.h: * Source/WebCore/Modules/mediastream/UserMediaClient.h: Ditto. * Source/WebCore/Modules/mediastream/UserMediaController.cpp: * Source/WebCore/Modules/mediastream/UserMediaController.h: (WebCore::UserMediaController::enumerateMediaDevices): Ditto. * Source/WebCore/Modules/mediastream/UserMediaRequest.cpp: (WebCore::UserMediaRequest::allow): Ditto. * Source/WebCore/Modules/mediastream/UserMediaRequest.h: * Source/WebCore/Modules/speech/SpeechRecognitionCaptureSource.cpp: (WebCore::SpeechRecognitionCaptureSource::createRealtimeMediaSource): Update for RealtimeMediaSource constructor changes. * Source/WebCore/Modules/webaudio/MediaStreamAudioSource.cpp: (WebCore::MediaStreamAudioSource::MediaStreamAudioSource): Ditto. * Source/WebCore/WebCore.xcodeproj/project.pbxproj: * Source/WebCore/platform/mediastream/CaptureDevice.h: (WebCore::CaptureDevice::CaptureDevice): Add `isEphemeral` parameter. (WebCore::CaptureDevice::setPersistentId): (WebCore::CaptureDevice::setLabel): (WebCore::CaptureDevice::isEphemeral const): (WebCore::CaptureDevice::setIsEphemeral): (WebCore::CaptureDevice::encode const): (WebCore::CaptureDevice::decode): (WebCore::CaptureDevice::isolatedCopy): * Source/WebCore/platform/mediastream/RealtimeIncomingAudioSource.cpp: (WebCore::RealtimeIncomingAudioSource::RealtimeIncomingAudioSource): Update for RealtimeMediaSource constructor changes. * Source/WebCore/platform/mediastream/RealtimeIncomingVideoSource.cpp: (WebCore::RealtimeIncomingVideoSource::RealtimeIncomingVideoSource): Ditto. * Source/WebCore/platform/mediastream/RealtimeMediaSource.cpp: (WebCore::toSourceType): (WebCore::RealtimeMediaSource::RealtimeMediaSource): Take a CaptureDevice instead of a type, name, and device ID. Take a MediaDeviceHashSalts instead of a String for the salts. (WebCore::RealtimeMediaSource::setPersistentId): (WebCore::RealtimeMediaSource::initializePersistentId): Calculate persistent and ephemeral hashed IDs. (WebCore::RealtimeMediaSource::fitnessDistance): m_hashedID -> hashedID() (WebCore::RealtimeMediaSource::hashedId const): Consider ephemeral state. (WebCore::RealtimeMediaSource::deviceIDHashSalts const): (WebCore::RealtimeMediaSource::setLogger): (WebCore::RealtimeMediaSource::deviceIDHashSalt const): Deleted. * Source/WebCore/platform/mediastream/RealtimeMediaSource.h: * Source/WebCore/platform/mediastream/RealtimeMediaSourceCenter.cpp: (WebCore::RealtimeMediaSourceCenter::createMediaStream): Take MediaDeviceHashSalts with the hash salts. (WebCore::RealtimeMediaSourceCenter::getDisplayMediaDevices): Ditto. (WebCore::RealtimeMediaSourceCenter::getUserMediaDevices): Ditto. (WebCore::RealtimeMediaSourceCenter::validateRequestConstraints): Ditto. (WebCore::RealtimeMediaSourceCenter::validateRequestConstraintsAfterEnumeration): Ditto. * Source/WebCore/platform/mediastream/RealtimeMediaSourceCenter.h: * Source/WebCore/platform/mediastream/RealtimeMediaSourceFactory.h: Ditto. * Source/WebCore/platform/mediastream/RealtimeMediaSourceSettings.h: Ditto. * Source/WebCore/platform/mediastream/RealtimeVideoCaptureSource.cpp: (WebCore::RealtimeVideoCaptureSource::RealtimeVideoCaptureSource): Update for RealtimeMediaSource constructor changes. * Source/WebCore/platform/mediastream/RealtimeVideoCaptureSource.h: * Source/WebCore/platform/mediastream/RealtimeVideoSource.cpp: (WebCore::RealtimeVideoSource::RealtimeVideoSource): Ditto. * Source/WebCore/platform/mediastream/cocoa/DisplayCaptureSourceCocoa.cpp: (WebCore::DisplayCaptureSourceCocoa::create): Ditto. (WebCore::DisplayCaptureSourceCocoa::DisplayCaptureSourceCocoa): Ditto. * Source/WebCore/platform/mediastream/cocoa/DisplayCaptureSourceCocoa.h: * Source/WebCore/platform/mediastream/ios/CoreAudioCaptureSourceIOS.h: * Source/WebCore/platform/mediastream/ios/CoreAudioCaptureSourceIOS.mm: (WebCore::CoreAudioCaptureSourceFactoryIOS::createAudioCaptureSource): Ditto. * Source/WebCore/platform/mediastream/mac/AVCaptureDeviceManager.mm: (WebCore::AVCaptureDeviceManager::updateCachedAVCaptureDevices): (WebCore::toCaptureDevice): Make Continuity Camera ephemeral when it is not the system preferred camera. (WebCore::AVCaptureDeviceManager::retrieveCaptureDevices): * Source/WebCore/platform/mediastream/mac/AVVideoCaptureSource.h: * Source/WebCore/platform/mediastream/mac/AVVideoCaptureSource.mm: (WebCore::AVVideoCaptureSource::create): Update for RealtimeMediaSource constructor changes. (WebCore::AVVideoCaptureSource::AVVideoCaptureSource): Ditto. * Source/WebCore/platform/mediastream/mac/CoreAudioCaptureSource.cpp: (WebCore::CoreAudioCaptureSource::create): Ditto. (WebCore::CoreAudioCaptureSource::createForTesting): Ditto. (WebCore::CoreAudioCaptureSource::CoreAudioCaptureSource): Ditto. * Source/WebCore/platform/mediastream/mac/CoreAudioCaptureSource.h: (WebCore::CoreAudioCaptureSourceFactory::createAudioCaptureSource): * Source/WebCore/platform/mediastream/mac/MockAudioSharedUnit.mm: (WebCore::MockRealtimeAudioSource::create): Ditto. * Source/WebCore/platform/mediastream/mac/MockRealtimeVideoSourceMac.h: * Source/WebCore/platform/mediastream/mac/MockRealtimeVideoSourceMac.mm: (WebCore::MockRealtimeVideoSource::create): Ditto. (WebCore::MockRealtimeVideoSourceMac::createForMockDisplayCapturer): Ditto. (WebCore::MockRealtimeVideoSourceMac::MockRealtimeVideoSourceMac): Ditto. * Source/WebCore/platform/mediastream/mac/RealtimeMediaSourceCenterMac.cpp: * Source/WebCore/platform/mock/MockMediaDevice.h: (WebCore::MockMediaDevice::captureDevice const): Allow to be ephemeral . (WebCore::MockMediaDevice::encode const): (WebCore::MockMediaDevice::decodeMockMediaDevice): (WebCore::MockMediaDevice::decode): * Source/WebCore/platform/mock/MockRealtimeAudioSource.cpp: (WebCore::MockRealtimeAudioSource::create): Update for RealtimeMediaSource constructor changes. (WebCore::MockRealtimeAudioSource::MockRealtimeAudioSource): Ditto. * Source/WebCore/platform/mock/MockRealtimeAudioSource.h: * Source/WebCore/platform/mock/MockRealtimeMediaSourceCenter.cpp: (WebCore::defaultDevices): No devices are ephemeral by default. (WebCore::MockDisplayCapturer::MockDisplayCapturer): Update for RealtimeMediaSource constructor changes. (WebCore::MockRealtimeMediaSourceCenter::setDeviceIsEphemeral): * Source/WebCore/platform/mock/MockRealtimeMediaSourceCenter.h: * Source/WebCore/platform/mock/MockRealtimeVideoSource.cpp: (WebCore::MockRealtimeVideoSource::create): Ditto. (WebCore::MockRealtimeVideoSource::MockRealtimeVideoSource): Ditto. * Source/WebCore/platform/mock/MockRealtimeVideoSource.h: * Source/WebKit/GPUProcess/GPUProcess.cpp: (WebKit::GPUProcess::setMockMediaDeviceIsEphemeral): Added for testing. * Source/WebKit/GPUProcess/GPUProcess.h: * Source/WebKit/GPUProcess/GPUProcess.messages.in: * Source/WebKit/UIProcess/API/C/WKMockMediaDevice.cpp: (WKAddMockMediaDevice): (WKSetMockMediaDeviceIsEphemeral): * Source/WebKit/UIProcess/API/C/WKMockMediaDevice.h: * Source/WebKit/UIProcess/Cocoa/UserMediaCaptureManagerProxy.cpp: (WebKit::UserMediaCaptureManagerProxy::createMicrophoneSource): (WebKit::UserMediaCaptureManagerProxy::createCameraSource): (WebKit::UserMediaCaptureManagerProxy::createMediaSourceForCaptureDeviceWithConstraints): * Source/WebKit/UIProcess/Cocoa/UserMediaCaptureManagerProxy.h: * Source/WebKit/UIProcess/Cocoa/UserMediaCaptureManagerProxy.messages.in: * Source/WebKit/UIProcess/GPU/GPUProcessProxy.cpp: (WebKit::GPUProcessProxy::setMockMediaDeviceIsEphemeral): * Source/WebKit/UIProcess/GPU/GPUProcessProxy.h: * Source/WebKit/UIProcess/SpeechRecognitionRemoteRealtimeMediaSource.cpp: (WebKit::SpeechRecognitionRemoteRealtimeMediaSource::SpeechRecognitionRemoteRealtimeMediaSource): (): Deleted. * Source/WebKit/UIProcess/UserMediaPermissionRequestManagerProxy.cpp: (WebKit::UserMediaPermissionRequestManagerProxy::finishGrantingRequest): Take MediaDeviceHashSalts for hash salts. (WebKit::UserMediaPermissionRequestManagerProxy::didCommitLoadForFrame): Clear ephemeral salt for a frame. (WebKit::UserMediaPermissionRequestManagerProxy::resetAccess): Ditto. (WebKit::UserMediaPermissionRequestManagerProxy::ephemeralDeviceHashSaltForFrame): Calculate or lookup an ephemeral salt for a frame. (WebKit::UserMediaPermissionRequestManagerProxy::processUserMediaPermissionRequest): Use MediaDeviceHashSalts. (WebKit::UserMediaPermissionRequestManagerProxy::platformValidateUserMediaRequestConstraints): Ditto. (WebKit::UserMediaPermissionRequestManagerProxy::processUserMediaPermissionValidRequest): Ditto. (WebKit::UserMediaPermissionRequestManagerProxy::enumerateMediaDevicesForFrame): Ditto. * Source/WebKit/UIProcess/UserMediaPermissionRequestManagerProxy.h: * Source/WebKit/UIProcess/UserMediaPermissionRequestProxy.h: (WebKit::UserMediaPermissionRequestProxy::setDeviceIdentifierHashSalts): *HashSalt -> *HashSalts (WebKit::UserMediaPermissionRequestProxy::deviceIdentifierHashSalts const): Ditto (WebKit::UserMediaPermissionRequestProxy::setDeviceIdentifierHashSalt): Deleted. (WebKit::UserMediaPermissionRequestProxy::deviceIdentifierHashSalt const): Deleted. * Source/WebKit/UIProcess/WebPageProxy.cpp: (WebKit::WebPageProxy::didCommitLoadForFrame): Let UserMediaPermissionRequestManager know the frame has reloaded so it can clear the ephemeral salt ID. (WebKit::WebPageProxy::enumerateMediaDevicesForFrame): * Source/WebKit/UIProcess/WebPageProxy.h: * Source/WebKit/UIProcess/WebPageProxy.messages.in: * Source/WebKit/UIProcess/WebProcessPool.cpp: (WebKit::WebProcessPool::setMockMediaDeviceIsEphemeral): * Source/WebKit/UIProcess/WebProcessPool.h: * Source/WebKit/WebProcess/MediaStream/UserMediaPermissionRequestManager.cpp: (WebKit::UserMediaPermissionRequestManager::userMediaAccessWasGranted): (WebKit::UserMediaPermissionRequestManager::enumerateMediaDevices): * Source/WebKit/WebProcess/MediaStream/UserMediaPermissionRequestManager.h: * Source/WebKit/WebProcess/WebCoreSupport/WebUserMediaClient.cpp: (WebKit::WebUserMediaClient::enumerateMediaDevices): * Source/WebKit/WebProcess/WebCoreSupport/WebUserMediaClient.h: * Source/WebKit/WebProcess/WebPage/WebPage.cpp: (WebKit::WebPage::userMediaAccessWasGranted): * Source/WebKit/WebProcess/WebPage/WebPage.h: * Source/WebKit/WebProcess/WebPage/WebPage.messages.in: * Source/WebKit/WebProcess/WebProcess.cpp: (WebKit::WebProcess::setMockMediaDeviceIsEphemeral): * Source/WebKit/WebProcess/WebProcess.h: * Source/WebKit/WebProcess/WebProcess.messages.in: * Source/WebKit/WebProcess/cocoa/RemoteRealtimeAudioSource.cpp: (WebKit::RemoteRealtimeAudioSource::create): Update for RealtimeMediaSource constructor change. (WebKit::RemoteRealtimeAudioSource::RemoteRealtimeAudioSource): Ditto. * Source/WebKit/WebProcess/cocoa/RemoteRealtimeAudioSource.h: * Source/WebKit/WebProcess/cocoa/RemoteRealtimeMediaSource.cpp: (WebKit::RemoteRealtimeMediaSource::RemoteRealtimeMediaSource): Ditto. (WebKit::RemoteRealtimeMediaSource::createRemoteMediaSource): Ditto. (WebKit::toSourceType): Deleted. (WebKit::m_manager): Deleted. * Source/WebKit/WebProcess/cocoa/RemoteRealtimeMediaSource.h: * Source/WebKit/WebProcess/cocoa/RemoteRealtimeMediaSourceProxy.cpp: (WebKit::RemoteRealtimeMediaSourceProxy::createRemoteMediaSource): Ditto. * Source/WebKit/WebProcess/cocoa/RemoteRealtimeMediaSourceProxy.h: * Source/WebKit/WebProcess/cocoa/RemoteRealtimeVideoSource.cpp: (WebKit::RemoteRealtimeVideoSource::create): Ditto. (WebKit::RemoteRealtimeVideoSource::RemoteRealtimeVideoSource): Ditto. (WebKit::RemoteRealtimeVideoSource::clone): Ditto. * Source/WebKit/WebProcess/cocoa/RemoteRealtimeVideoSource.h: * Source/WebKit/WebProcess/cocoa/UserMediaCaptureManager.cpp: (WebKit::UserMediaCaptureManager::AudioFactory::createAudioCaptureSource): Ditto. (WebKit::UserMediaCaptureManager::VideoFactory::createVideoCaptureSource): Ditto. (WebKit::UserMediaCaptureManager::DisplayFactory::createDisplayCaptureSource): Ditto. * Source/WebKit/WebProcess/cocoa/UserMediaCaptureManager.h: * Tools/WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl: Add setMockMediaDeviceIsEphemeral. * Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp: (WTR::TestRunner::setMockMediaDeviceIsEphemeral): * Tools/WebKitTestRunner/InjectedBundle/TestRunner.h: * Tools/WebKitTestRunner/TestController.cpp: (WTR::TestController::setMockMediaDeviceIsEphemeral): * Tools/WebKitTestRunner/TestController.h: * Tools/WebKitTestRunner/TestInvocation.cpp: (WTR::TestInvocation::didReceiveSynchronousMessageFromInjectedBundle): Canonical link: https://commits.webkit.org/256161@main Canonical link: https://commits.webkit.org/252432.811@safari-7614.3.7.1-branch --- ...numerate-devices-ephemeral-id-expected.txt | 4 ++ .../enumerate-devices-ephemeral-id.html | 72 +++++++++++++++++++ ...enumerate-devices-ephemeral-id-iframe.html | 29 ++++++++ Source/WTF/wtf/PlatformHave.h | 5 ++ Source/WebCore/Headers.cmake | 1 + .../CanvasCaptureMediaStreamTrack.cpp | 2 +- .../mediastream/MediaDeviceHashSalts.h | 60 ++++++++++++++++ .../Modules/mediastream/MediaDevices.cpp | 15 ++-- .../Modules/mediastream/MediaDevices.h | 2 +- .../Modules/mediastream/UserMediaClient.h | 7 +- .../mediastream/UserMediaController.cpp | 3 +- .../Modules/mediastream/UserMediaController.h | 4 +- .../Modules/mediastream/UserMediaRequest.cpp | 2 +- .../Modules/mediastream/UserMediaRequest.h | 2 +- .../speech/SpeechRecognitionCaptureSource.cpp | 2 +- .../webaudio/MediaStreamAudioSource.cpp | 2 +- .../WebCore/WebCore.xcodeproj/project.pbxproj | 4 ++ .../platform/mediastream/CaptureDevice.h | 19 ++++- .../RealtimeIncomingAudioSource.cpp | 2 +- .../RealtimeIncomingVideoSource.cpp | 2 +- .../mediastream/RealtimeMediaSource.cpp | 56 ++++++++++----- .../mediastream/RealtimeMediaSource.h | 16 +++-- .../mediastream/RealtimeMediaSourceCenter.cpp | 35 ++++----- .../mediastream/RealtimeMediaSourceCenter.h | 13 ++-- .../mediastream/RealtimeMediaSourceFactory.h | 6 +- .../RealtimeVideoCaptureSource.cpp | 6 +- .../mediastream/RealtimeVideoCaptureSource.h | 4 +- .../mediastream/RealtimeVideoSource.cpp | 4 +- .../cocoa/DisplayCaptureSourceCocoa.cpp | 19 ++--- .../cocoa/DisplayCaptureSourceCocoa.h | 6 +- .../gstreamer/GStreamerAudioCaptureSource.cpp | 12 ++-- .../gstreamer/GStreamerAudioCaptureSource.h | 4 +- .../gstreamer/GStreamerCaptureDeviceManager.h | 2 +- .../GStreamerDisplayCaptureDeviceManager.cpp | 6 +- .../gstreamer/GStreamerVideoCaptureSource.cpp | 24 +++---- .../gstreamer/GStreamerVideoCaptureSource.h | 8 +-- .../MockRealtimeAudioSourceGStreamer.cpp | 12 ++-- .../MockRealtimeAudioSourceGStreamer.h | 4 +- .../MockRealtimeVideoSourceGStreamer.cpp | 20 +++--- .../MockRealtimeVideoSourceGStreamer.h | 6 +- .../RealtimeIncomingAudioSourceGStreamer.cpp | 2 +- .../RealtimeIncomingSourceGStreamer.cpp | 4 +- .../RealtimeIncomingSourceGStreamer.h | 2 +- .../RealtimeIncomingVideoSourceGStreamer.cpp | 2 +- .../ios/CoreAudioCaptureSourceIOS.h | 4 +- .../ios/CoreAudioCaptureSourceIOS.mm | 6 +- .../mediastream/mac/AVCaptureDeviceManager.mm | 27 ++++--- .../mediastream/mac/AVVideoCaptureSource.h | 4 +- .../mediastream/mac/AVVideoCaptureSource.mm | 8 +-- .../mac/CoreAudioCaptureSource.cpp | 16 ++--- .../mediastream/mac/CoreAudioCaptureSource.h | 14 ++-- .../mediastream/mac/MockAudioSharedUnit.mm | 4 +- .../mac/MockRealtimeVideoSourceMac.h | 6 +- .../mac/MockRealtimeVideoSourceMac.mm | 14 ++-- .../mac/RealtimeMediaSourceCenterMac.cpp | 8 +-- .../WebCore/platform/mock/MockMediaDevice.h | 29 +++++--- .../platform/mock/MockRealtimeAudioSource.cpp | 10 +-- .../platform/mock/MockRealtimeAudioSource.h | 6 +- .../mock/MockRealtimeMediaSourceCenter.cpp | 57 +++++++++------ .../mock/MockRealtimeMediaSourceCenter.h | 3 +- .../platform/mock/MockRealtimeVideoSource.cpp | 10 +-- .../platform/mock/MockRealtimeVideoSource.h | 6 +- Source/WebKit/GPUProcess/GPUProcess.cpp | 5 ++ Source/WebKit/GPUProcess/GPUProcess.h | 3 +- .../WebKit/GPUProcess/GPUProcess.messages.in | 1 + .../UIProcess/API/C/WKMockMediaDevice.cpp | 7 +- .../UIProcess/API/C/WKMockMediaDevice.h | 1 + .../Cocoa/UserMediaCaptureManagerProxy.cpp | 18 ++--- .../Cocoa/UserMediaCaptureManagerProxy.h | 8 +-- .../UserMediaCaptureManagerProxy.messages.in | 4 +- .../WebKit/UIProcess/GPU/GPUProcessProxy.cpp | 5 ++ Source/WebKit/UIProcess/GPU/GPUProcessProxy.h | 1 + ...chRecognitionRemoteRealtimeMediaSource.cpp | 2 +- ...UserMediaPermissionRequestManagerProxy.cpp | 60 ++++++++++++---- .../UserMediaPermissionRequestManagerProxy.h | 12 ++-- .../UserMediaPermissionRequestProxy.h | 9 +-- Source/WebKit/UIProcess/WebPageProxy.cpp | 7 +- Source/WebKit/UIProcess/WebPageProxy.h | 4 +- .../WebKit/UIProcess/WebPageProxy.messages.in | 2 +- Source/WebKit/UIProcess/WebProcessPool.cpp | 12 ++++ Source/WebKit/UIProcess/WebProcessPool.h | 3 +- ...MediaPermissionRequestManagerProxyGLib.cpp | 6 +- .../UserMediaPermissionRequestManager.cpp | 8 +-- .../UserMediaPermissionRequestManager.h | 4 +- .../WebCoreSupport/WebUserMediaClient.cpp | 2 +- .../WebCoreSupport/WebUserMediaClient.h | 2 +- Source/WebKit/WebProcess/WebPage/WebPage.cpp | 4 +- Source/WebKit/WebProcess/WebPage/WebPage.h | 2 +- .../WebProcess/WebPage/WebPage.messages.in | 2 +- Source/WebKit/WebProcess/WebProcess.cpp | 5 ++ Source/WebKit/WebProcess/WebProcess.h | 3 +- .../WebKit/WebProcess/WebProcess.messages.in | 1 + .../cocoa/RemoteRealtimeAudioSource.cpp | 10 +-- .../cocoa/RemoteRealtimeAudioSource.h | 7 +- .../cocoa/RemoteRealtimeMediaSource.cpp | 27 ++----- .../cocoa/RemoteRealtimeMediaSource.h | 4 +- .../cocoa/RemoteRealtimeMediaSourceProxy.cpp | 6 +- .../cocoa/RemoteRealtimeMediaSourceProxy.h | 4 +- .../cocoa/RemoteRealtimeVideoSource.cpp | 14 ++-- .../cocoa/RemoteRealtimeVideoSource.h | 6 +- .../cocoa/UserMediaCaptureManager.cpp | 14 ++-- .../cocoa/UserMediaCaptureManager.h | 6 +- .../glib/UserMediaCaptureManager.cpp | 11 +-- .../WebProcess/glib/UserMediaCaptureManager.h | 5 +- .../glib/UserMediaCaptureManager.messages.in | 2 +- .../InjectedBundle/Bindings/TestRunner.idl | 1 + .../InjectedBundle/TestRunner.cpp | 8 +++ .../InjectedBundle/TestRunner.h | 1 + Tools/WebKitTestRunner/TestController.cpp | 5 ++ Tools/WebKitTestRunner/TestController.h | 1 + Tools/WebKitTestRunner/TestInvocation.cpp | 8 +++ 111 files changed, 723 insertions(+), 364 deletions(-) create mode 100644 LayoutTests/http/tests/media/media-stream/enumerate-devices-ephemeral-id-expected.txt create mode 100644 LayoutTests/http/tests/media/media-stream/enumerate-devices-ephemeral-id.html create mode 100644 LayoutTests/http/tests/media/media-stream/resources/enumerate-devices-ephemeral-id-iframe.html create mode 100644 Source/WebCore/Modules/mediastream/MediaDeviceHashSalts.h diff --git a/LayoutTests/http/tests/media/media-stream/enumerate-devices-ephemeral-id-expected.txt b/LayoutTests/http/tests/media/media-stream/enumerate-devices-ephemeral-id-expected.txt new file mode 100644 index 000000000000..6df96e590fe1 --- /dev/null +++ b/LayoutTests/http/tests/media/media-stream/enumerate-devices-ephemeral-id-expected.txt @@ -0,0 +1,4 @@ + + +PASS Ephemeral device IDs + diff --git a/LayoutTests/http/tests/media/media-stream/enumerate-devices-ephemeral-id.html b/LayoutTests/http/tests/media/media-stream/enumerate-devices-ephemeral-id.html new file mode 100644 index 000000000000..a948e0b7ca1b --- /dev/null +++ b/LayoutTests/http/tests/media/media-stream/enumerate-devices-ephemeral-id.html @@ -0,0 +1,72 @@ + + + + + + + + + diff --git a/LayoutTests/http/tests/media/media-stream/resources/enumerate-devices-ephemeral-id-iframe.html b/LayoutTests/http/tests/media/media-stream/resources/enumerate-devices-ephemeral-id-iframe.html new file mode 100644 index 000000000000..f6ea5223c892 --- /dev/null +++ b/LayoutTests/http/tests/media/media-stream/resources/enumerate-devices-ephemeral-id-iframe.html @@ -0,0 +1,29 @@ + + +
+ + diff --git a/Source/WTF/wtf/PlatformHave.h b/Source/WTF/wtf/PlatformHave.h index db9b2a27b19e..e5d05be60df5 100644 --- a/Source/WTF/wtf/PlatformHave.h +++ b/Source/WTF/wtf/PlatformHave.h @@ -1349,3 +1349,8 @@ || (PLATFORM(APPLETV) && __TV_OS_VERSION_MIN_REQUIRED >= 140000) #define HAVE_ACCESSIBILITY_FRAMEWORK 1 #endif + +#if (PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 130000) \ + || ((PLATFORM(IOS) || PLATFORM(MACCATALYST)) && __IPHONE_OS_VERSION_MIN_REQUIRED >= 160000) +#define HAVE_CONTINUITY_CAMEARA 1 +#endif diff --git a/Source/WebCore/Headers.cmake b/Source/WebCore/Headers.cmake index 1dea0788cf4d..a3d3b45a2764 100644 --- a/Source/WebCore/Headers.cmake +++ b/Source/WebCore/Headers.cmake @@ -265,6 +265,7 @@ set(WebCore_PRIVATE_FRAMEWORK_HEADERS Modules/mediastream/DetachedRTCDataChannel.h Modules/mediastream/DoubleRange.h Modules/mediastream/LongRange.h + Modules/mediastream/MediaDeviceHashSalts.h Modules/mediastream/MediaStreamTrack.h Modules/mediastream/MediaTrackConstraints.h Modules/mediastream/RTCController.h diff --git a/Source/WebCore/Modules/mediastream/CanvasCaptureMediaStreamTrack.cpp b/Source/WebCore/Modules/mediastream/CanvasCaptureMediaStreamTrack.cpp index 915ae8cdf886..4c954fa9ceb0 100644 --- a/Source/WebCore/Modules/mediastream/CanvasCaptureMediaStreamTrack.cpp +++ b/Source/WebCore/Modules/mediastream/CanvasCaptureMediaStreamTrack.cpp @@ -77,7 +77,7 @@ const char* CanvasCaptureMediaStreamTrack::activeDOMObjectName() const // FIXME: Give source id and name CanvasCaptureMediaStreamTrack::Source::Source(HTMLCanvasElement& canvas, std::optional&& frameRequestRate) - : RealtimeMediaSource(Type::Video, "CanvasCaptureMediaStreamTrack"_s) + : RealtimeMediaSource(CaptureDevice { { }, CaptureDevice::DeviceType::Camera, "CanvasCaptureMediaStreamTrack"_s }) , m_frameRequestRate(WTFMove(frameRequestRate)) , m_requestFrameTimer(*this, &Source::requestFrameTimerFired) , m_captureCanvasTimer(*this, &Source::captureCanvas) diff --git a/Source/WebCore/Modules/mediastream/MediaDeviceHashSalts.h b/Source/WebCore/Modules/mediastream/MediaDeviceHashSalts.h new file mode 100644 index 000000000000..aa4123fe2b41 --- /dev/null +++ b/Source/WebCore/Modules/mediastream/MediaDeviceHashSalts.h @@ -0,0 +1,60 @@ +/* + * 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. ``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 + * 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 + +#include +#include + +namespace WebCore { + +struct MediaDeviceHashSalts { + String persistentDeviceSalt; + String ephemeralDeviceSalt; + + template void encode(Encoder&) const; + template static WARN_UNUSED_RETURN bool decode(Decoder&, MediaDeviceHashSalts&); +}; + +template +void MediaDeviceHashSalts::encode(Encoder& encoder) const +{ + encoder << persistentDeviceSalt + << ephemeralDeviceSalt; +} + +template +bool MediaDeviceHashSalts::decode(Decoder& decoder, MediaDeviceHashSalts& settings) +{ + return decoder.decode(settings.persistentDeviceSalt) + && decoder.decode(settings.ephemeralDeviceSalt); +} + +} // namespace WebCore + +namespace WTF { +template<> struct DefaultHash; +template<> struct HashTraits; +} diff --git a/Source/WebCore/Modules/mediastream/MediaDevices.cpp b/Source/WebCore/Modules/mediastream/MediaDevices.cpp index 39048b1abb62..aad6b04696ac 100644 --- a/Source/WebCore/Modules/mediastream/MediaDevices.cpp +++ b/Source/WebCore/Modules/mediastream/MediaDevices.cpp @@ -290,7 +290,7 @@ static inline MediaDeviceInfo::Kind toMediaDeviceInfoKind(CaptureDevice::DeviceT return MediaDeviceInfo::Kind::Audioinput; } -void MediaDevices::exposeDevices(const Vector& newDevices, const String& deviceIDHashSalt, EnumerateDevicesPromise&& promise) +void MediaDevices::exposeDevices(const Vector& newDevices, MediaDeviceHashSalts&& deviceIDHashSalts, EnumerateDevicesPromise&& promise) { if (isContextStopped()) return; @@ -312,8 +312,13 @@ void MediaDevices::exposeDevices(const Vector& newDevices, const if (!canAccessSpeaker && newDevice.type() == CaptureDevice::DeviceType::Speaker) continue; - auto deviceId = RealtimeMediaSourceCenter::singleton().hashStringWithSalt(newDevice.persistentId(), deviceIDHashSalt); - auto groupId = RealtimeMediaSourceCenter::singleton().hashStringWithSalt(newDevice.groupId(), m_groupIdHashSalt); + auto& center = RealtimeMediaSourceCenter::singleton(); + String deviceId; + if (newDevice.isEphemeral()) + deviceId = center.hashStringWithSalt(newDevice.persistentId(), deviceIDHashSalts.ephemeralDeviceSalt); + else + deviceId = center.hashStringWithSalt(newDevice.persistentId(), deviceIDHashSalts.persistentDeviceSalt); + auto groupId = center.hashStringWithSalt(newDevice.groupId(), m_groupIdHashSalt); if (newDevice.type() == CaptureDevice::DeviceType::Speaker) m_audioOutputDeviceIdToPersistentId.add(deviceId, newDevice.persistentId()); @@ -341,10 +346,10 @@ void MediaDevices::enumerateDevices(EnumerateDevicesPromise&& promise) return; } - controller->enumerateMediaDevices(*document, [this, weakThis = WeakPtr { *this }, promise = WTFMove(promise)](const auto& newDevices, const auto& deviceIDHashSalt) mutable { + controller->enumerateMediaDevices(*document, [this, weakThis = WeakPtr { *this }, promise = WTFMove(promise)](const auto& newDevices, MediaDeviceHashSalts&& deviceIDHashSalts) mutable { if (!weakThis) return; - exposeDevices(newDevices, deviceIDHashSalt, WTFMove(promise)); + exposeDevices(newDevices, WTFMove(deviceIDHashSalts), WTFMove(promise)); }); } diff --git a/Source/WebCore/Modules/mediastream/MediaDevices.h b/Source/WebCore/Modules/mediastream/MediaDevices.h index 7d00ea256e2d..2688d321e7af 100644 --- a/Source/WebCore/Modules/mediastream/MediaDevices.h +++ b/Source/WebCore/Modules/mediastream/MediaDevices.h @@ -101,7 +101,7 @@ class MediaDevices final : public RefCounted, public ActiveDOMObje void scheduledEventTimerFired(); bool addEventListener(const AtomString& eventType, Ref&&, const AddEventListenerOptions&) override; - void exposeDevices(const Vector&, const String&, EnumerateDevicesPromise&&); + void exposeDevices(const Vector&, MediaDeviceHashSalts&&, EnumerateDevicesPromise&&); void listenForDeviceChanges(); friend class JSMediaDevicesOwner; diff --git a/Source/WebCore/Modules/mediastream/UserMediaClient.h b/Source/WebCore/Modules/mediastream/UserMediaClient.h index f56959732940..7eab3e781d6d 100644 --- a/Source/WebCore/Modules/mediastream/UserMediaClient.h +++ b/Source/WebCore/Modules/mediastream/UserMediaClient.h @@ -1,6 +1,6 @@ /* * Copyright (C) 2011 Ericsson AB. All rights reserved. - * Copyright (C) 2016-2018 Apple Inc. All rights reserved. + * Copyright (C) 2016-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 @@ -43,6 +43,8 @@ class Document; class Page; class UserMediaRequest; +struct MediaDeviceHashSalts; + class UserMediaClient { public: virtual void pageDestroyed() = 0; @@ -50,7 +52,8 @@ class UserMediaClient { virtual void requestUserMediaAccess(UserMediaRequest&) = 0; virtual void cancelUserMediaAccessRequest(UserMediaRequest&) = 0; - virtual void enumerateMediaDevices(Document&, CompletionHandler&, const String&)>&&) = 0; + using EnumerateDevicesCallback = CompletionHandler&, MediaDeviceHashSalts&&)>; + virtual void enumerateMediaDevices(Document&, EnumerateDevicesCallback&&) = 0; enum DeviceChangeObserverTokenType { }; using DeviceChangeObserverToken = ObjectIdentifier; diff --git a/Source/WebCore/Modules/mediastream/UserMediaController.cpp b/Source/WebCore/Modules/mediastream/UserMediaController.cpp index eb3cb2f087a8..16f9ce84cabb 100644 --- a/Source/WebCore/Modules/mediastream/UserMediaController.cpp +++ b/Source/WebCore/Modules/mediastream/UserMediaController.cpp @@ -30,8 +30,7 @@ #include "DOMWindow.h" #include "Document.h" -#include "Frame.h" -#include "HTMLIFrameElement.h" +#include "RealtimeMediaSourceCenter.h" #include "UserMediaRequest.h" namespace WebCore { diff --git a/Source/WebCore/Modules/mediastream/UserMediaController.h b/Source/WebCore/Modules/mediastream/UserMediaController.h index 43cc83acb5c8..3042f9a10832 100644 --- a/Source/WebCore/Modules/mediastream/UserMediaController.h +++ b/Source/WebCore/Modules/mediastream/UserMediaController.h @@ -47,7 +47,7 @@ class UserMediaController : public Supplement { void requestUserMediaAccess(UserMediaRequest&); void cancelUserMediaAccessRequest(UserMediaRequest&); - void enumerateMediaDevices(Document&, CompletionHandler&, const String&)>&&); + void enumerateMediaDevices(Document&, UserMediaClient::EnumerateDevicesCallback&&); UserMediaClient::DeviceChangeObserverToken addDeviceChangeObserver(Function&&); void removeDeviceChangeObserver(UserMediaClient::DeviceChangeObserverToken); @@ -73,7 +73,7 @@ inline void UserMediaController::cancelUserMediaAccessRequest(UserMediaRequest& m_client->cancelUserMediaAccessRequest(request); } -inline void UserMediaController::enumerateMediaDevices(Document& document, CompletionHandler&, const String&)>&& completionHandler) +inline void UserMediaController::enumerateMediaDevices(Document& document, UserMediaClient::EnumerateDevicesCallback&& completionHandler) { m_client->enumerateMediaDevices(document, WTFMove(completionHandler)); } diff --git a/Source/WebCore/Modules/mediastream/UserMediaRequest.cpp b/Source/WebCore/Modules/mediastream/UserMediaRequest.cpp index 28f0583af0a5..9d4bb2ad4c1a 100644 --- a/Source/WebCore/Modules/mediastream/UserMediaRequest.cpp +++ b/Source/WebCore/Modules/mediastream/UserMediaRequest.cpp @@ -149,7 +149,7 @@ static inline bool isMediaStreamCorrectlyStarted(const MediaStream& stream) }); } -void UserMediaRequest::allow(CaptureDevice&& audioDevice, CaptureDevice&& videoDevice, String&& deviceIdentifierHashSalt, CompletionHandler&& completionHandler) +void UserMediaRequest::allow(CaptureDevice&& audioDevice, CaptureDevice&& videoDevice, MediaDeviceHashSalts&& deviceIdentifierHashSalt, CompletionHandler&& completionHandler) { RELEASE_LOG(MediaStream, "UserMediaRequest::allow %s %s", audioDevice ? audioDevice.persistentId().utf8().data() : "", videoDevice ? videoDevice.persistentId().utf8().data() : ""); m_allowCompletionHandler = WTFMove(completionHandler); diff --git a/Source/WebCore/Modules/mediastream/UserMediaRequest.h b/Source/WebCore/Modules/mediastream/UserMediaRequest.h index c36242eaf529..7e8c67b4d5d7 100644 --- a/Source/WebCore/Modules/mediastream/UserMediaRequest.h +++ b/Source/WebCore/Modules/mediastream/UserMediaRequest.h @@ -63,7 +63,7 @@ class UserMediaRequest : public RefCounted, public ActiveDOMOb void start(); WEBCORE_EXPORT void setAllowedMediaDeviceUIDs(const String& audioDeviceUID, const String& videoDeviceUID); - WEBCORE_EXPORT void allow(CaptureDevice&& audioDevice, CaptureDevice&& videoDevice, String&& deviceIdentifierHashSalt, CompletionHandler&&); + WEBCORE_EXPORT void allow(CaptureDevice&& audioDevice, CaptureDevice&& videoDevice, MediaDeviceHashSalts&&, CompletionHandler&&); enum MediaAccessDenialReason { NoConstraints, UserMediaDisabled, NoCaptureDevices, InvalidConstraint, HardwareError, PermissionDenied, InvalidAccess, OtherFailure }; WEBCORE_EXPORT void deny(MediaAccessDenialReason, const String& errorMessage = emptyString()); diff --git a/Source/WebCore/Modules/speech/SpeechRecognitionCaptureSource.cpp b/Source/WebCore/Modules/speech/SpeechRecognitionCaptureSource.cpp index afbce7a9f456..d0b3ae07ad31 100644 --- a/Source/WebCore/Modules/speech/SpeechRecognitionCaptureSource.cpp +++ b/Source/WebCore/Modules/speech/SpeechRecognitionCaptureSource.cpp @@ -64,7 +64,7 @@ std::optional SpeechRecognitionCaptureSource::findCaptureDevice() CaptureSourceOrError SpeechRecognitionCaptureSource::createRealtimeMediaSource(const CaptureDevice& captureDevice, PageIdentifier pageIdentifier) { - return RealtimeMediaSourceCenter::singleton().audioCaptureFactory().createAudioCaptureSource(captureDevice, "SpeechID"_s, { }, pageIdentifier); + return RealtimeMediaSourceCenter::singleton().audioCaptureFactory().createAudioCaptureSource(captureDevice, { "SpeechID"_s, "SpeechID"_s }, { }, pageIdentifier); } SpeechRecognitionCaptureSource::SpeechRecognitionCaptureSource(SpeechRecognitionConnectionClientIdentifier clientIdentifier, DataCallback&& dataCallback, StateUpdateCallback&& stateUpdateCallback, Ref&& source) diff --git a/Source/WebCore/Modules/webaudio/MediaStreamAudioSource.cpp b/Source/WebCore/Modules/webaudio/MediaStreamAudioSource.cpp index 4fc7b8e96a88..f5eb918a4ff5 100644 --- a/Source/WebCore/Modules/webaudio/MediaStreamAudioSource.cpp +++ b/Source/WebCore/Modules/webaudio/MediaStreamAudioSource.cpp @@ -34,7 +34,7 @@ namespace WebCore { MediaStreamAudioSource::MediaStreamAudioSource(float sampleRate) - : RealtimeMediaSource(RealtimeMediaSource::Type::Audio, "MediaStreamAudioDestinationNode"_s) + : RealtimeMediaSource(CaptureDevice { { }, CaptureDevice::DeviceType::Microphone, "MediaStreamAudioDestinationNode"_s }) { m_currentSettings.setSampleRate(sampleRate); } diff --git a/Source/WebCore/WebCore.xcodeproj/project.pbxproj b/Source/WebCore/WebCore.xcodeproj/project.pbxproj index 9712576855ae..16017c2dce40 100644 --- a/Source/WebCore/WebCore.xcodeproj/project.pbxproj +++ b/Source/WebCore/WebCore.xcodeproj/project.pbxproj @@ -128,6 +128,7 @@ 0754A5EA215EA3B8002D3A99 /* RealtimeMediaSourceFactory.h in Headers */ = {isa = PBXBuildFile; fileRef = 0754A5E8215EA3B7002D3A99 /* RealtimeMediaSourceFactory.h */; settings = {ATTRIBUTES = (Private, ); }; }; 0757B13E214AE79900794B0D /* VideoPreset.h in Headers */ = {isa = PBXBuildFile; fileRef = 0757B13C214AE79700794B0D /* VideoPreset.h */; settings = {ATTRIBUTES = (Private, ); }; }; 07611DC12440E59B00D80704 /* MediaUsageInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 07611DB8243FB75C00D80704 /* MediaUsageInfo.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 07637267290330610055DDA2 /* MediaDeviceHashSalts.h in Headers */ = {isa = PBXBuildFile; fileRef = 0763726629030BB50055DDA2 /* MediaDeviceHashSalts.h */; settings = {ATTRIBUTES = (Private, ); }; }; 07638A991884487200E15A1B /* MediaSessionManagerIOS.h in Headers */ = {isa = PBXBuildFile; fileRef = 07638A971884487200E15A1B /* MediaSessionManagerIOS.h */; settings = {ATTRIBUTES = (Private, ); }; }; 07638A9A1884487200E15A1B /* MediaSessionManagerIOS.mm in Sources */ = {isa = PBXBuildFile; fileRef = 07638A981884487200E15A1B /* MediaSessionManagerIOS.mm */; }; 076970871463AD8700F502CF /* TextTrackList.h in Headers */ = {isa = PBXBuildFile; fileRef = 076970851463AD8700F502CF /* TextTrackList.h */; }; @@ -6176,6 +6177,7 @@ 0754A5E8215EA3B7002D3A99 /* RealtimeMediaSourceFactory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RealtimeMediaSourceFactory.h; sourceTree = ""; }; 0757B13C214AE79700794B0D /* VideoPreset.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VideoPreset.h; sourceTree = ""; }; 07611DB8243FB75C00D80704 /* MediaUsageInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MediaUsageInfo.h; sourceTree = ""; }; + 0763726629030BB50055DDA2 /* MediaDeviceHashSalts.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MediaDeviceHashSalts.h; sourceTree = ""; }; 07638A971884487200E15A1B /* MediaSessionManagerIOS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MediaSessionManagerIOS.h; sourceTree = ""; }; 07638A981884487200E15A1B /* MediaSessionManagerIOS.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MediaSessionManagerIOS.mm; sourceTree = ""; }; 076970841463AD8700F502CF /* TextTrackList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TextTrackList.cpp; sourceTree = ""; }; @@ -18700,6 +18702,7 @@ 93A806121E03B51C008A1F26 /* DoubleRange.idl */, 93A806131E03B51C008A1F26 /* LongRange.h */, 93A806141E03B51C008A1F26 /* LongRange.idl */, + 0763726629030BB50055DDA2 /* MediaDeviceHashSalts.h */, 159AE82A1B3A402F0037478B /* MediaDeviceInfo.cpp */, 15145B8F1B3A1B3E00662BF7 /* MediaDeviceInfo.h */, 15145B911B3A1D4C00662BF7 /* MediaDeviceInfo.idl */, @@ -36831,6 +36834,7 @@ CD3EEF3825799F73006563BB /* MediaDecodingConfiguration.h in Headers */, CD3EEF3E25799FC7006563BB /* MediaDecodingType.h in Headers */, CDF2B004181F059C00F2B424 /* MediaDescription.h in Headers */, + 07637267290330610055DDA2 /* MediaDeviceHashSalts.h in Headers */, 15145B901B3A1CE000662BF7 /* MediaDeviceInfo.h in Headers */, 5EA725D31ACABD4700EAD17B /* MediaDevices.h in Headers */, 97205AB81239291000B17380 /* MediaDocument.h in Headers */, diff --git a/Source/WebCore/platform/mediastream/CaptureDevice.h b/Source/WebCore/platform/mediastream/CaptureDevice.h index e50dccf5d5dd..1f4b39b5ad51 100644 --- a/Source/WebCore/platform/mediastream/CaptureDevice.h +++ b/Source/WebCore/platform/mediastream/CaptureDevice.h @@ -33,7 +33,7 @@ class CaptureDevice { public: enum class DeviceType { Unknown, Microphone, Speaker, Camera, Screen, Window, SystemAudio }; - CaptureDevice(const String& persistentId, DeviceType type, const String& label, const String& groupId = emptyString(), bool isEnabled = false, bool isDefault = false, bool isMock = false) + CaptureDevice(const String& persistentId, DeviceType type, const String& label, const String& groupId = emptyString(), bool isEnabled = false, bool isDefault = false, bool isMock = false, bool isEphemeral = false) : m_persistentId(persistentId) , m_type(type) , m_label(label) @@ -41,13 +41,16 @@ class CaptureDevice { , m_enabled(isEnabled) , m_default(isDefault) , m_isMockDevice(isMock) + , m_isEphemeral(isEphemeral) { } CaptureDevice() = default; + void setPersistentId(const String& persistentId) { m_persistentId = persistentId; } const String& persistentId() const { return m_persistentId; } + void setLabel(const String& label) { m_label = label; } const String& label() const { static NeverDestroyed airPods(MAKE_STATIC_STRING_IMPL("AirPods")); @@ -72,6 +75,9 @@ class CaptureDevice { bool isMockDevice() const { return m_isMockDevice; } void setIsMockDevice(bool isMockDevice) { m_isMockDevice = isMockDevice; } + bool isEphemeral() const { return m_isEphemeral; } + void setIsEphemeral(bool isEphemeral) { m_isEphemeral = isEphemeral; } + explicit operator bool() const { return m_type != DeviceType::Unknown; } CaptureDevice isolatedCopy() &&; @@ -87,6 +93,7 @@ class CaptureDevice { encoder << m_default; encoder << m_type; encoder << m_isMockDevice; + encoder << m_isEphemeral; } template @@ -127,10 +134,16 @@ class CaptureDevice { if (!isMockDevice) return std::nullopt; + std::optional isEphemeral; + decoder >> isEphemeral; + if (!isEphemeral) + return std::nullopt; + std::optional device = {{ WTFMove(*persistentId), WTFMove(*type), WTFMove(*label), WTFMove(*groupId) }}; device->setEnabled(*enabled); device->setIsDefault(*isDefault); device->setIsMockDevice(*isMockDevice); + device->setIsEphemeral(*isEphemeral); return device; } #endif @@ -143,6 +156,7 @@ class CaptureDevice { bool m_enabled { false }; bool m_default { false }; bool m_isMockDevice { false }; + bool m_isEphemeral { false }; }; inline bool haveDevicesChanged(const Vector& oldDevices, const Vector& newDevices) @@ -174,7 +188,8 @@ inline CaptureDevice CaptureDevice::isolatedCopy() && WTFMove(m_groupId).isolatedCopy(), m_enabled, m_default, - m_isMockDevice + m_isMockDevice, + m_isEphemeral }; } diff --git a/Source/WebCore/platform/mediastream/RealtimeIncomingAudioSource.cpp b/Source/WebCore/platform/mediastream/RealtimeIncomingAudioSource.cpp index 119c30509f49..70479a5b40c5 100644 --- a/Source/WebCore/platform/mediastream/RealtimeIncomingAudioSource.cpp +++ b/Source/WebCore/platform/mediastream/RealtimeIncomingAudioSource.cpp @@ -40,7 +40,7 @@ namespace WebCore { RealtimeIncomingAudioSource::RealtimeIncomingAudioSource(rtc::scoped_refptr&& audioTrack, String&& audioTrackId) - : RealtimeMediaSource(RealtimeMediaSource::Type::Audio, "remote audio"_s, WTFMove(audioTrackId)) + : RealtimeMediaSource(CaptureDevice { WTFMove(audioTrackId), CaptureDevice::DeviceType::Microphone, "remote audio"_s }) , m_audioTrack(WTFMove(audioTrack)) { ASSERT(m_audioTrack); diff --git a/Source/WebCore/platform/mediastream/RealtimeIncomingVideoSource.cpp b/Source/WebCore/platform/mediastream/RealtimeIncomingVideoSource.cpp index 9c634da391ec..106458c9ce07 100644 --- a/Source/WebCore/platform/mediastream/RealtimeIncomingVideoSource.cpp +++ b/Source/WebCore/platform/mediastream/RealtimeIncomingVideoSource.cpp @@ -36,7 +36,7 @@ namespace WebCore { RealtimeIncomingVideoSource::RealtimeIncomingVideoSource(rtc::scoped_refptr&& videoTrack, String&& videoTrackId) - : RealtimeMediaSource(Type::Video, "remote video"_s, WTFMove(videoTrackId)) + : RealtimeMediaSource(CaptureDevice { WTFMove(videoTrackId), CaptureDevice::DeviceType::Camera, "remote video"_s }) , m_videoTrack(WTFMove(videoTrack)) { ASSERT(m_videoTrack); diff --git a/Source/WebCore/platform/mediastream/RealtimeMediaSource.cpp b/Source/WebCore/platform/mediastream/RealtimeMediaSource.cpp index fbffb66563bc..f895c3d85f7e 100644 --- a/Source/WebCore/platform/mediastream/RealtimeMediaSource.cpp +++ b/Source/WebCore/platform/mediastream/RealtimeMediaSource.cpp @@ -48,28 +48,49 @@ namespace WebCore { -RealtimeMediaSource::RealtimeMediaSource(Type type, AtomString&& name, String&& deviceID, String&& hashSalt, PageIdentifier pageIdentifier) +static RealtimeMediaSource::Type toSourceType(CaptureDevice::DeviceType type) +{ + switch (type) { + case CaptureDevice::DeviceType::Microphone: + case CaptureDevice::DeviceType::SystemAudio: + return RealtimeMediaSource::Type::Audio; + case CaptureDevice::DeviceType::Camera: + case CaptureDevice::DeviceType::Screen: + case CaptureDevice::DeviceType::Window: + return RealtimeMediaSource::Type::Video; + case CaptureDevice::DeviceType::Unknown: + case CaptureDevice::DeviceType::Speaker: + ASSERT_NOT_REACHED(); + return RealtimeMediaSource::Type::Audio; + } + ASSERT_NOT_REACHED(); + return RealtimeMediaSource::Type::Audio; +} + +RealtimeMediaSource::RealtimeMediaSource(const CaptureDevice& device, MediaDeviceHashSalts&& hashSalts, PageIdentifier pageIdentifier) : m_pageIdentifier(pageIdentifier) - , m_idHashSalt(WTFMove(hashSalt)) - , m_persistentID(WTFMove(deviceID)) - , m_type(type) - , m_name(WTFMove(name)) + , m_idHashSalts(WTFMove(hashSalts)) + , m_type(toSourceType(device.type())) + , m_name({ device.label() }) + , m_device(device) { initializePersistentId(); } void RealtimeMediaSource::setPersistentId(const String& persistentID) { - m_persistentID = persistentID; + m_device.setPersistentId(persistentID); initializePersistentId(); } void RealtimeMediaSource::initializePersistentId() { - if (m_persistentID.isEmpty()) - m_persistentID = createVersion4UUIDString(); + if (m_device.persistentId().isEmpty()) + m_device.setPersistentId(createVersion4UUIDString()); - m_hashedID = AtomString { RealtimeMediaSourceCenter::singleton().hashStringWithSalt(m_persistentID, m_idHashSalt) }; + auto& center = RealtimeMediaSourceCenter::singleton(); + m_hashedID = AtomString { center.hashStringWithSalt(m_device.persistentId(), m_idHashSalts.persistentDeviceSalt) }; + m_ephemeralHashedID = AtomString { center.hashStringWithSalt(m_device.persistentId(), m_idHashSalts.ephemeralDeviceSalt) }; } void RealtimeMediaSource::addAudioSampleObserver(AudioSampleObserver& observer) @@ -496,8 +517,8 @@ double RealtimeMediaSource::fitnessDistance(const MediaConstraint& constraint) case MediaConstraintType::DeviceId: ASSERT(constraint.isString()); - ASSERT(!m_hashedID.isEmpty()); - return downcast(constraint).fitnessDistance(m_hashedID); + ASSERT(!hashedId().isEmpty()); + return downcast(constraint).fitnessDistance(hashedId()); break; case MediaConstraintType::GroupId: { @@ -1109,15 +1130,18 @@ void RealtimeMediaSource::scheduleDeferredTask(Function&& function) const AtomString& RealtimeMediaSource::hashedId() const { -#ifndef NDEBUG ASSERT(!m_hashedID.isEmpty()); -#endif + ASSERT(!m_ephemeralHashedID.isEmpty()); + + if (isEphemeral()) + return m_ephemeralHashedID; + return m_hashedID; } -String RealtimeMediaSource::deviceIDHashSalt() const +const MediaDeviceHashSalts& RealtimeMediaSource::deviceIDHashSalts() const { - return m_idHashSalt; + return m_idHashSalts; } void RealtimeMediaSource::setType(Type type) @@ -1143,7 +1167,7 @@ void RealtimeMediaSource::setLogger(const Logger& newLogger, const void* newLogI { m_logger = &newLogger; m_logIdentifier = newLogIdentifier; - ALWAYS_LOG(LOGIDENTIFIER, m_type, ", ", m_name, ", ", m_hashedID); + ALWAYS_LOG(LOGIDENTIFIER, m_type, ", ", name(), ", ", m_hashedID, ", ", m_ephemeralHashedID); } WTFLogChannel& RealtimeMediaSource::logChannel() const diff --git a/Source/WebCore/platform/mediastream/RealtimeMediaSource.h b/Source/WebCore/platform/mediastream/RealtimeMediaSource.h index f065253874de..bd7ef7cd6ccf 100644 --- a/Source/WebCore/platform/mediastream/RealtimeMediaSource.h +++ b/Source/WebCore/platform/mediastream/RealtimeMediaSource.h @@ -38,6 +38,7 @@ #include "CaptureDevice.h" #include "Image.h" #include "MediaConstraints.h" +#include "MediaDeviceHashSalts.h" #include "PlatformLayer.h" #include "RealtimeMediaSourceCapabilities.h" #include "RealtimeMediaSourceFactory.h" @@ -120,9 +121,9 @@ class WEBCORE_EXPORT RealtimeMediaSource virtual Ref clone() { return *this; } const AtomString& hashedId() const; - String deviceIDHashSalt() const; + const MediaDeviceHashSalts& deviceIDHashSalts() const; - const String& persistentID() const { return m_persistentID; } + const String& persistentID() const { return m_device.persistentId(); } enum class Type : bool { Audio, Video }; Type type() const { return m_type; } @@ -233,8 +234,11 @@ class WEBCORE_EXPORT RealtimeMediaSource PageIdentifier pageIdentifier() const { return m_pageIdentifier; } + const CaptureDevice& captureDevice() const { return m_device; } + bool isEphemeral() const { return m_device.isEphemeral(); } + protected: - RealtimeMediaSource(Type, AtomString&& name, String&& deviceID = { }, String&& hashSalt = { }, PageIdentifier = { }); + RealtimeMediaSource(const CaptureDevice&, MediaDeviceHashSalts&& hashSalts = { }, PageIdentifier = { }); void scheduleDeferredTask(Function&&); @@ -291,9 +295,9 @@ class WEBCORE_EXPORT RealtimeMediaSource #endif PageIdentifier m_pageIdentifier; - String m_idHashSalt; + MediaDeviceHashSalts m_idHashSalts; AtomString m_hashedID; - String m_persistentID; + AtomString m_ephemeralHashedID; Type m_type; AtomString m_name; WeakHashSet m_observers; @@ -304,6 +308,8 @@ class WEBCORE_EXPORT RealtimeMediaSource mutable Lock m_VideoFrameObserversLock; HashSet m_VideoFrameObservers WTF_GUARDED_BY_LOCK(m_VideoFrameObserversLock); + CaptureDevice m_device; + // Set on the main thread from constraints. IntSize m_size; // Set on sample generation thread. diff --git a/Source/WebCore/platform/mediastream/RealtimeMediaSourceCenter.cpp b/Source/WebCore/platform/mediastream/RealtimeMediaSourceCenter.cpp index 4f7ec79ddebe..77908c0941f7 100644 --- a/Source/WebCore/platform/mediastream/RealtimeMediaSourceCenter.cpp +++ b/Source/WebCore/platform/mediastream/RealtimeMediaSourceCenter.cpp @@ -37,8 +37,11 @@ #include "DisplayCaptureManager.h" #include "Logging.h" +#include "MediaDeviceHashSalts.h" #include "MediaStreamPrivate.h" #include +#include +#include #include namespace WebCore { @@ -69,7 +72,7 @@ RealtimeMediaSourceCenter::~RealtimeMediaSourceCenter() = default; RealtimeMediaSourceCenter::Observer::~Observer() = default; -void RealtimeMediaSourceCenter::createMediaStream(Ref&& logger, NewMediaStreamHandler&& completionHandler, String&& hashSalt, CaptureDevice&& audioDevice, CaptureDevice&& videoDevice, const MediaStreamRequest& request) +void RealtimeMediaSourceCenter::createMediaStream(Ref&& logger, NewMediaStreamHandler&& completionHandler, MediaDeviceHashSalts&& hashSalts, CaptureDevice&& audioDevice, CaptureDevice&& videoDevice, const MediaStreamRequest& request) { Vector> audioSources; Vector> videoSources; @@ -77,7 +80,7 @@ void RealtimeMediaSourceCenter::createMediaStream(Ref&& logger, Ne RefPtr audioSource; if (audioDevice) { - auto source = audioCaptureFactory().createAudioCaptureSource(WTFMove(audioDevice), String { hashSalt }, &request.audioConstraints, request.pageIdentifier); + auto source = audioCaptureFactory().createAudioCaptureSource(WTFMove(audioDevice), MediaDeviceHashSalts { hashSalts }, &request.audioConstraints, request.pageIdentifier); if (!source) { completionHandler(makeUnexpected(makeString("Failed to create MediaStream audio source: ", source.errorMessage))); return; @@ -89,9 +92,9 @@ void RealtimeMediaSourceCenter::createMediaStream(Ref&& logger, Ne if (videoDevice) { CaptureSourceOrError source; if (videoDevice.type() == CaptureDevice::DeviceType::Camera) - source = videoCaptureFactory().createVideoCaptureSource(WTFMove(videoDevice), WTFMove(hashSalt), &request.videoConstraints, request.pageIdentifier); + source = videoCaptureFactory().createVideoCaptureSource(WTFMove(videoDevice), WTFMove(hashSalts), &request.videoConstraints, request.pageIdentifier); else - source = displayCaptureFactory().createDisplayCaptureSource(WTFMove(videoDevice), WTFMove(hashSalt), &request.videoConstraints, request.pageIdentifier); + source = displayCaptureFactory().createDisplayCaptureSource(WTFMove(videoDevice), WTFMove(hashSalts), &request.videoConstraints, request.pageIdentifier); if (!source) { completionHandler(makeUnexpected(makeString("Failed to create MediaStream video source: ", source.errorMessage))); @@ -194,7 +197,7 @@ void RealtimeMediaSourceCenter::triggerDevicesChangedObservers() }); } -void RealtimeMediaSourceCenter::getDisplayMediaDevices(const MediaStreamRequest& request, String&& hashSalt, Vector& displayDeviceInfo, String& firstInvalidConstraint) +void RealtimeMediaSourceCenter::getDisplayMediaDevices(const MediaStreamRequest& request, MediaDeviceHashSalts&& hashSalts, Vector& displayDeviceInfo, String& firstInvalidConstraint) { if (!request.videoConstraints.isValid) return; @@ -204,7 +207,7 @@ void RealtimeMediaSourceCenter::getDisplayMediaDevices(const MediaStreamRequest& if (!device.enabled()) return; - auto sourceOrError = displayCaptureFactory().createDisplayCaptureSource(device, String { hashSalt }, &request.videoConstraints, request.pageIdentifier); + auto sourceOrError = displayCaptureFactory().createDisplayCaptureSource(device, MediaDeviceHashSalts { hashSalts }, &request.videoConstraints, request.pageIdentifier); if (sourceOrError && sourceOrError.captureSource->supportsConstraints(request.videoConstraints, invalidConstraint)) displayDeviceInfo.append({ sourceOrError.captureSource->fitnessScore(), device }); @@ -213,7 +216,7 @@ void RealtimeMediaSourceCenter::getDisplayMediaDevices(const MediaStreamRequest& } } -void RealtimeMediaSourceCenter::getUserMediaDevices(const MediaStreamRequest& request, String&& hashSalt, Vector& audioDeviceInfo, Vector& videoDeviceInfo, String& firstInvalidConstraint) +void RealtimeMediaSourceCenter::getUserMediaDevices(const MediaStreamRequest& request, MediaDeviceHashSalts&& hashSalts, Vector& audioDeviceInfo, Vector& videoDeviceInfo, String& firstInvalidConstraint) { String invalidConstraint; if (request.audioConstraints.isValid) { @@ -221,7 +224,7 @@ void RealtimeMediaSourceCenter::getUserMediaDevices(const MediaStreamRequest& re if (!device.enabled()) continue; - auto sourceOrError = audioCaptureFactory().createAudioCaptureSource(device, String { hashSalt }, { }, request.pageIdentifier); + auto sourceOrError = audioCaptureFactory().createAudioCaptureSource(device, MediaDeviceHashSalts { hashSalts }, { }, request.pageIdentifier); if (sourceOrError && sourceOrError.captureSource->supportsConstraints(request.audioConstraints, invalidConstraint)) audioDeviceInfo.append({sourceOrError.captureSource->fitnessScore(), device}); @@ -235,7 +238,7 @@ void RealtimeMediaSourceCenter::getUserMediaDevices(const MediaStreamRequest& re if (!device.enabled()) continue; - auto sourceOrError = videoCaptureFactory().createVideoCaptureSource(device, String { hashSalt }, { }, request.pageIdentifier); + auto sourceOrError = videoCaptureFactory().createVideoCaptureSource(device, MediaDeviceHashSalts { hashSalts }, { }, request.pageIdentifier); if (sourceOrError && sourceOrError.captureSource->supportsConstraints(request.videoConstraints, invalidConstraint)) videoDeviceInfo.append({sourceOrError.captureSource->fitnessScore(), device}); @@ -258,18 +261,18 @@ void RealtimeMediaSourceCenter::enumerateDevices(bool shouldEnumerateCamera, boo audioCaptureFactory().computeSpeakerDevices([callbackAggregator] { }); } -void RealtimeMediaSourceCenter::validateRequestConstraints(ValidConstraintsHandler&& validHandler, InvalidConstraintsHandler&& invalidHandler, const MediaStreamRequest& request, String&& deviceIdentifierHashSalt) +void RealtimeMediaSourceCenter::validateRequestConstraints(ValidConstraintsHandler&& validHandler, InvalidConstraintsHandler&& invalidHandler, const MediaStreamRequest& request, MediaDeviceHashSalts&& deviceIdentifierHashSalts) { bool shouldEnumerateCamera = request.videoConstraints.isValid; bool shouldEnumerateDisplay = (request.type == MediaStreamRequest::Type::DisplayMedia || request.type == MediaStreamRequest::Type::DisplayMediaWithAudio); bool shouldEnumerateMicrophone = request.audioConstraints.isValid; bool shouldEnumerateSpeakers = false; - enumerateDevices(shouldEnumerateCamera, shouldEnumerateDisplay, shouldEnumerateMicrophone, shouldEnumerateSpeakers, [this, validHandler = WTFMove(validHandler), invalidHandler = WTFMove(invalidHandler), request, deviceIdentifierHashSalt = WTFMove(deviceIdentifierHashSalt)]() mutable { - validateRequestConstraintsAfterEnumeration(WTFMove(validHandler), WTFMove(invalidHandler), request, WTFMove(deviceIdentifierHashSalt)); + enumerateDevices(shouldEnumerateCamera, shouldEnumerateDisplay, shouldEnumerateMicrophone, shouldEnumerateSpeakers, [this, validHandler = WTFMove(validHandler), invalidHandler = WTFMove(invalidHandler), request, deviceIdentifierHashSalts = WTFMove(deviceIdentifierHashSalts)]() mutable { + validateRequestConstraintsAfterEnumeration(WTFMove(validHandler), WTFMove(invalidHandler), request, WTFMove(deviceIdentifierHashSalts)); }); } -void RealtimeMediaSourceCenter::validateRequestConstraintsAfterEnumeration(ValidConstraintsHandler&& validHandler, InvalidConstraintsHandler&& invalidHandler, const MediaStreamRequest& request, String&& deviceIdentifierHashSalt) +void RealtimeMediaSourceCenter::validateRequestConstraintsAfterEnumeration(ValidConstraintsHandler&& validHandler, InvalidConstraintsHandler&& invalidHandler, const MediaStreamRequest& request, MediaDeviceHashSalts&& deviceIdentifierHashSalts) { struct { bool operator()(const DeviceInfo& a, const DeviceInfo& b) @@ -283,9 +286,9 @@ void RealtimeMediaSourceCenter::validateRequestConstraintsAfterEnumeration(Valid String firstInvalidConstraint; if (request.type == MediaStreamRequest::Type::DisplayMedia || request.type == MediaStreamRequest::Type::DisplayMediaWithAudio) - getDisplayMediaDevices(request, String { deviceIdentifierHashSalt }, videoDeviceInfo, firstInvalidConstraint); + getDisplayMediaDevices(request, MediaDeviceHashSalts { deviceIdentifierHashSalts }, videoDeviceInfo, firstInvalidConstraint); else - getUserMediaDevices(request, String { deviceIdentifierHashSalt }, audioDeviceInfo, videoDeviceInfo, firstInvalidConstraint); + getUserMediaDevices(request, MediaDeviceHashSalts { deviceIdentifierHashSalts }, audioDeviceInfo, videoDeviceInfo, firstInvalidConstraint); if (request.audioConstraints.isValid && audioDeviceInfo.isEmpty()) { WTFLogAlways("Audio capture was requested but no device was found amongst %zu devices", audioCaptureFactory().audioCaptureDeviceManager().captureDevices().size()); @@ -319,7 +322,7 @@ void RealtimeMediaSourceCenter::validateRequestConstraintsAfterEnumeration(Valid }); } - validHandler(WTFMove(audioDevices), WTFMove(videoDevices), WTFMove(deviceIdentifierHashSalt)); + validHandler(WTFMove(audioDevices), WTFMove(videoDevices)); } void RealtimeMediaSourceCenter::setAudioCaptureFactory(AudioCaptureFactory& factory) diff --git a/Source/WebCore/platform/mediastream/RealtimeMediaSourceCenter.h b/Source/WebCore/platform/mediastream/RealtimeMediaSourceCenter.h index 138e6507c6ef..16673de162f7 100644 --- a/Source/WebCore/platform/mediastream/RealtimeMediaSourceCenter.h +++ b/Source/WebCore/platform/mediastream/RealtimeMediaSourceCenter.h @@ -39,7 +39,6 @@ #include "RealtimeMediaSource.h" #include "RealtimeMediaSourceFactory.h" #include "RealtimeMediaSourceSupportedConstraints.h" -#include "UserMediaClient.h" #include #include #include @@ -73,12 +72,12 @@ class WEBCORE_EXPORT RealtimeMediaSourceCenter : public ThreadSafeRefCounted&& audioDeviceUIDs, Vector&& videoDeviceUIDs, String&&)>; + using ValidConstraintsHandler = Function&& audioDeviceUIDs, Vector&& videoDeviceUIDs)>; using InvalidConstraintsHandler = Function; - WEBCORE_EXPORT void validateRequestConstraints(ValidConstraintsHandler&&, InvalidConstraintsHandler&&, const MediaStreamRequest&, String&&); + WEBCORE_EXPORT void validateRequestConstraints(ValidConstraintsHandler&&, InvalidConstraintsHandler&&, const MediaStreamRequest&, MediaDeviceHashSalts&&); using NewMediaStreamHandler = Function, String>&&)>; - void createMediaStream(Ref&&, NewMediaStreamHandler&&, String&&, CaptureDevice&& audioDevice, CaptureDevice&& videoDevice, const MediaStreamRequest&); + void createMediaStream(Ref&&, NewMediaStreamHandler&&, MediaDeviceHashSalts&&, CaptureDevice&& audioDevice, CaptureDevice&& videoDevice, const MediaStreamRequest&); WEBCORE_EXPORT void getMediaStreamDevices(CompletionHandler&&)>&&); @@ -123,9 +122,9 @@ class WEBCORE_EXPORT RealtimeMediaSourceCenter : public ThreadSafeRefCounted&, String&); - void getUserMediaDevices(const MediaStreamRequest&, String&&, Vector& audioDevices, Vector& videoDevices, String&); - void validateRequestConstraintsAfterEnumeration(ValidConstraintsHandler&&, InvalidConstraintsHandler&&, const MediaStreamRequest&, String&&); + void getDisplayMediaDevices(const MediaStreamRequest&, MediaDeviceHashSalts&&, Vector&, String&); + void getUserMediaDevices(const MediaStreamRequest&, MediaDeviceHashSalts&&, Vector& audioDevices, Vector& videoDevices, String&); + void validateRequestConstraintsAfterEnumeration(ValidConstraintsHandler&&, InvalidConstraintsHandler&&, const MediaStreamRequest&, MediaDeviceHashSalts&&); void enumerateDevices(bool shouldEnumerateCamera, bool shouldEnumerateDisplay, bool shouldEnumerateMicrophone, bool shouldEnumerateSpeakers, CompletionHandler&&); RealtimeMediaSourceSupportedConstraints m_supportedConstraints; diff --git a/Source/WebCore/platform/mediastream/RealtimeMediaSourceFactory.h b/Source/WebCore/platform/mediastream/RealtimeMediaSourceFactory.h index 661d592eec20..f66259af2ebf 100644 --- a/Source/WebCore/platform/mediastream/RealtimeMediaSourceFactory.h +++ b/Source/WebCore/platform/mediastream/RealtimeMediaSourceFactory.h @@ -45,7 +45,7 @@ struct MediaConstraints; class AudioCaptureFactory { public: virtual ~AudioCaptureFactory() = default; - virtual CaptureSourceOrError createAudioCaptureSource(const CaptureDevice&, String&&, const MediaConstraints*, PageIdentifier) = 0; + virtual CaptureSourceOrError createAudioCaptureSource(const CaptureDevice&, MediaDeviceHashSalts&&, const MediaConstraints*, PageIdentifier) = 0; virtual CaptureDeviceManager& audioCaptureDeviceManager() = 0; virtual const Vector& speakerDevices() const = 0; virtual void computeSpeakerDevices(CompletionHandler&& callback) const { callback(); } @@ -61,7 +61,7 @@ class AudioCaptureFactory { class VideoCaptureFactory { public: virtual ~VideoCaptureFactory() = default; - virtual CaptureSourceOrError createVideoCaptureSource(const CaptureDevice&, String&&, const MediaConstraints*, PageIdentifier) = 0; + virtual CaptureSourceOrError createVideoCaptureSource(const CaptureDevice&, MediaDeviceHashSalts&&, const MediaConstraints*, PageIdentifier) = 0; virtual CaptureDeviceManager& videoCaptureDeviceManager() = 0; protected: @@ -71,7 +71,7 @@ class VideoCaptureFactory { class DisplayCaptureFactory { public: virtual ~DisplayCaptureFactory() = default; - virtual CaptureSourceOrError createDisplayCaptureSource(const CaptureDevice&, String&&, const MediaConstraints*, PageIdentifier) = 0; + virtual CaptureSourceOrError createDisplayCaptureSource(const CaptureDevice&, MediaDeviceHashSalts&&, const MediaConstraints*, PageIdentifier) = 0; virtual DisplayCaptureManager& displayCaptureDeviceManager() = 0; protected: diff --git a/Source/WebCore/platform/mediastream/RealtimeVideoCaptureSource.cpp b/Source/WebCore/platform/mediastream/RealtimeVideoCaptureSource.cpp index 1b53688b5f51..5ab57cc093ce 100644 --- a/Source/WebCore/platform/mediastream/RealtimeVideoCaptureSource.cpp +++ b/Source/WebCore/platform/mediastream/RealtimeVideoCaptureSource.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2019 Apple Inc. All rights reserved. + * Copyright (C) 2018-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 @@ -35,8 +35,8 @@ namespace WebCore { -RealtimeVideoCaptureSource::RealtimeVideoCaptureSource(AtomString&& name, String&& id, String&& hashSalt, PageIdentifier pageIdentifier) - : RealtimeMediaSource(Type::Video, WTFMove(name), WTFMove(id), WTFMove(hashSalt), pageIdentifier) +RealtimeVideoCaptureSource::RealtimeVideoCaptureSource(const CaptureDevice& device, MediaDeviceHashSalts&& hashSalts, PageIdentifier pageIdentifier) + : RealtimeMediaSource(device, WTFMove(hashSalts), pageIdentifier) { } diff --git a/Source/WebCore/platform/mediastream/RealtimeVideoCaptureSource.h b/Source/WebCore/platform/mediastream/RealtimeVideoCaptureSource.h index b129508a938e..29b52ae7d9e4 100644 --- a/Source/WebCore/platform/mediastream/RealtimeVideoCaptureSource.h +++ b/Source/WebCore/platform/mediastream/RealtimeVideoCaptureSource.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2019 Apple Inc. All rights reserved. + * Copyright (C) 2018-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 @@ -55,7 +55,7 @@ class WEBCORE_EXPORT RealtimeVideoCaptureSource : public RealtimeMediaSource { const VideoPreset* currentPreset() const { return m_currentPreset.get(); } protected: - RealtimeVideoCaptureSource(AtomString&& name, String&& id, String&& hashSalt, PageIdentifier); + RealtimeVideoCaptureSource(const CaptureDevice&, MediaDeviceHashSalts&&, PageIdentifier); void setSizeAndFrameRate(std::optional width, std::optional height, std::optional) override; diff --git a/Source/WebCore/platform/mediastream/RealtimeVideoSource.cpp b/Source/WebCore/platform/mediastream/RealtimeVideoSource.cpp index 9aecd715243c..88cadf9664a7 100644 --- a/Source/WebCore/platform/mediastream/RealtimeVideoSource.cpp +++ b/Source/WebCore/platform/mediastream/RealtimeVideoSource.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 Apple Inc. All rights reserved. + * Copyright (C) 2019-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 @@ -36,7 +36,7 @@ namespace WebCore { RealtimeVideoSource::RealtimeVideoSource(Ref&& source, bool shouldUseIOSurface) - : RealtimeMediaSource(Type::Video, AtomString { source->name() }, String { source->persistentID() }, String { source->deviceIDHashSalt() }, source->pageIdentifier()) + : RealtimeMediaSource(source->captureDevice(), MediaDeviceHashSalts { source->deviceIDHashSalts() }, source->pageIdentifier()) , m_source(WTFMove(source)) #if PLATFORM(COCOA) , m_shouldUseIOSurface(shouldUseIOSurface) diff --git a/Source/WebCore/platform/mediastream/cocoa/DisplayCaptureSourceCocoa.cpp b/Source/WebCore/platform/mediastream/cocoa/DisplayCaptureSourceCocoa.cpp index db5ab9806bec..1321ecc982da 100644 --- a/Source/WebCore/platform/mediastream/cocoa/DisplayCaptureSourceCocoa.cpp +++ b/Source/WebCore/platform/mediastream/cocoa/DisplayCaptureSourceCocoa.cpp @@ -31,6 +31,7 @@ #include "CGDisplayStreamScreenCaptureSource.h" #include "ImageTransferSessionVT.h" #include "Logging.h" +#include "MediaDeviceHashSalts.h" #include "MediaSampleAVFObjC.h" #include "RealtimeMediaSource.h" #include "RealtimeMediaSourceCenter.h" @@ -59,23 +60,23 @@ namespace WebCore { -CaptureSourceOrError DisplayCaptureSourceCocoa::create(const CaptureDevice& device, String&& hashSalt, const MediaConstraints* constraints, PageIdentifier pageIdentifier) +CaptureSourceOrError DisplayCaptureSourceCocoa::create(const CaptureDevice& device, MediaDeviceHashSalts&& hashSalts, const MediaConstraints* constraints, PageIdentifier pageIdentifier) { switch (device.type()) { case CaptureDevice::DeviceType::Screen: #if PLATFORM(IOS) - return create(ReplayKitCaptureSource::create(device.persistentId()), device, WTFMove(hashSalt), constraints, pageIdentifier); + return create(ReplayKitCaptureSource::create(device.persistentId()), device, WTFMove(hashSalts), constraints, pageIdentifier); #else #if HAVE(SCREEN_CAPTURE_KIT) if (ScreenCaptureKitCaptureSource::isAvailable()) - return create(ScreenCaptureKitCaptureSource::create(device, constraints), device, WTFMove(hashSalt), constraints, pageIdentifier); + return create(ScreenCaptureKitCaptureSource::create(device, constraints), device, WTFMove(hashSalts), constraints, pageIdentifier); #endif - return create(CGDisplayStreamScreenCaptureSource::create(device.persistentId()), device, WTFMove(hashSalt), constraints, pageIdentifier); + return create(CGDisplayStreamScreenCaptureSource::create(device.persistentId()), device, WTFMove(hashSalts), constraints, pageIdentifier); #endif case CaptureDevice::DeviceType::Window: #if HAVE(SCREEN_CAPTURE_KIT) if (ScreenCaptureKitCaptureSource::isAvailable()) - return create(ScreenCaptureKitCaptureSource::create(device, constraints), device, WTFMove(hashSalt), constraints, pageIdentifier); + return create(ScreenCaptureKitCaptureSource::create(device, constraints), device, WTFMove(hashSalts), constraints, pageIdentifier); #endif break; case CaptureDevice::DeviceType::SystemAudio: @@ -90,12 +91,12 @@ CaptureSourceOrError DisplayCaptureSourceCocoa::create(const CaptureDevice& devi return { }; } -CaptureSourceOrError DisplayCaptureSourceCocoa::create(Expected, String>&& capturer, const CaptureDevice& device, String&& hashSalt, const MediaConstraints* constraints, PageIdentifier pageIdentifier) +CaptureSourceOrError DisplayCaptureSourceCocoa::create(Expected, String>&& capturer, const CaptureDevice& device, MediaDeviceHashSalts&& hashSalts, const MediaConstraints* constraints, PageIdentifier pageIdentifier) { if (!capturer.has_value()) return CaptureSourceOrError { WTFMove(capturer.error()) }; - auto source = adoptRef(*new DisplayCaptureSourceCocoa(WTFMove(capturer.value()), AtomString { device.label() }, String { device.persistentId() }, WTFMove(hashSalt), pageIdentifier)); + auto source = adoptRef(*new DisplayCaptureSourceCocoa(WTFMove(capturer.value()), device, WTFMove(hashSalts), pageIdentifier)); if (constraints) { auto result = source->applyConstraints(*constraints); if (result) @@ -105,8 +106,8 @@ CaptureSourceOrError DisplayCaptureSourceCocoa::create(Expected&& capturer, AtomString&& name, String&& deviceID, String&& hashSalt, PageIdentifier pageIdentifier) - : RealtimeMediaSource(RealtimeMediaSource::Type::Video, WTFMove(name), WTFMove(deviceID), WTFMove(hashSalt), pageIdentifier) +DisplayCaptureSourceCocoa::DisplayCaptureSourceCocoa(UniqueRef&& capturer, const CaptureDevice& device, MediaDeviceHashSalts&& hashSalts, PageIdentifier pageIdentifier) + : RealtimeMediaSource(device, WTFMove(hashSalts), pageIdentifier) , m_capturer(WTFMove(capturer)) , m_timer(RunLoop::current(), this, &DisplayCaptureSourceCocoa::emitFrame) , m_userActivity("App nap disabled for screen capture") diff --git a/Source/WebCore/platform/mediastream/cocoa/DisplayCaptureSourceCocoa.h b/Source/WebCore/platform/mediastream/cocoa/DisplayCaptureSourceCocoa.h index 6b7852bb1db0..ed7032551984 100644 --- a/Source/WebCore/platform/mediastream/cocoa/DisplayCaptureSourceCocoa.h +++ b/Source/WebCore/platform/mediastream/cocoa/DisplayCaptureSourceCocoa.h @@ -114,14 +114,14 @@ class DisplayCaptureSourceCocoa final const void* m_logIdentifier; }; - static CaptureSourceOrError create(const CaptureDevice&, String&&, const MediaConstraints*, PageIdentifier); - static CaptureSourceOrError create(Expected, String>&&, const CaptureDevice&, String&&, const MediaConstraints*, PageIdentifier); + static CaptureSourceOrError create(const CaptureDevice&, MediaDeviceHashSalts&&, const MediaConstraints*, PageIdentifier); + static CaptureSourceOrError create(Expected, String>&&, const CaptureDevice&, MediaDeviceHashSalts&&, const MediaConstraints*, PageIdentifier); Seconds elapsedTime(); void updateFrameSize(); private: - DisplayCaptureSourceCocoa(UniqueRef&&, AtomString&& name, String&& deviceID, String&& hashSalt, PageIdentifier); + DisplayCaptureSourceCocoa(UniqueRef&&, const CaptureDevice&, MediaDeviceHashSalts&&, PageIdentifier); virtual ~DisplayCaptureSourceCocoa(); // RealtimeMediaSource diff --git a/Source/WebCore/platform/mediastream/gstreamer/GStreamerAudioCaptureSource.cpp b/Source/WebCore/platform/mediastream/gstreamer/GStreamerAudioCaptureSource.cpp index 8cda296a90dd..6ba26a028871 100644 --- a/Source/WebCore/platform/mediastream/gstreamer/GStreamerAudioCaptureSource.cpp +++ b/Source/WebCore/platform/mediastream/gstreamer/GStreamerAudioCaptureSource.cpp @@ -56,9 +56,9 @@ static void initializeDebugCategory() class GStreamerAudioCaptureSourceFactory : public AudioCaptureFactory { public: - CaptureSourceOrError createAudioCaptureSource(const CaptureDevice& device, String&& hashSalt, const MediaConstraints* constraints, PageIdentifier) final + CaptureSourceOrError createAudioCaptureSource(const CaptureDevice& device, MediaDeviceHashSalts&& hashSalts, const MediaConstraints* constraints, PageIdentifier) final { - return GStreamerAudioCaptureSource::create(String { device.persistentId() }, WTFMove(hashSalt), constraints); + return GStreamerAudioCaptureSource::create(String { device.persistentId() }, WTFMove(hashSalts), constraints); } private: CaptureDeviceManager& audioCaptureDeviceManager() final { return GStreamerAudioCaptureDeviceManager::singleton(); } @@ -73,7 +73,7 @@ static GStreamerAudioCaptureSourceFactory& libWebRTCAudioCaptureSourceFactory() return factory.get(); } -CaptureSourceOrError GStreamerAudioCaptureSource::create(String&& deviceID, String&& hashSalt, const MediaConstraints* constraints) +CaptureSourceOrError GStreamerAudioCaptureSource::create(String&& deviceID, MediaDeviceHashSalts&& hashSalts, const MediaConstraints* constraints) { auto device = GStreamerAudioCaptureDeviceManager::singleton().gstreamerDeviceWithUID(deviceID); if (!device) { @@ -81,7 +81,7 @@ CaptureSourceOrError GStreamerAudioCaptureSource::create(String&& deviceID, Stri return CaptureSourceOrError(WTFMove(errorMessage)); } - auto source = adoptRef(*new GStreamerAudioCaptureSource(device.value(), WTFMove(hashSalt))); + auto source = adoptRef(*new GStreamerAudioCaptureSource(device.value(), WTFMove(hashSalts))); if (constraints) { if (auto result = source->applyConstraints(*constraints)) @@ -95,8 +95,8 @@ AudioCaptureFactory& GStreamerAudioCaptureSource::factory() return libWebRTCAudioCaptureSourceFactory(); } -GStreamerAudioCaptureSource::GStreamerAudioCaptureSource(GStreamerCaptureDevice device, String&& hashSalt) - : RealtimeMediaSource(RealtimeMediaSource::Type::Audio, AtomString { device.persistentId() }, String { device.label() }, WTFMove(hashSalt)) +GStreamerAudioCaptureSource::GStreamerAudioCaptureSource(GStreamerCaptureDevice device, MediaDeviceHashSalts&& hashSalts) + : RealtimeMediaSource(device, WTFMove(hashSalts)) , m_capturer(makeUnique(device)) { initializeDebugCategory(); diff --git a/Source/WebCore/platform/mediastream/gstreamer/GStreamerAudioCaptureSource.h b/Source/WebCore/platform/mediastream/gstreamer/GStreamerAudioCaptureSource.h index 212321e2b739..dee902daa9d3 100644 --- a/Source/WebCore/platform/mediastream/gstreamer/GStreamerAudioCaptureSource.h +++ b/Source/WebCore/platform/mediastream/gstreamer/GStreamerAudioCaptureSource.h @@ -32,7 +32,7 @@ namespace WebCore { class GStreamerAudioCaptureSource : public RealtimeMediaSource { public: - static CaptureSourceOrError create(String&& deviceID, String&& hashSalt, const MediaConstraints*); + static CaptureSourceOrError create(String&& deviceID, MediaDeviceHashSalts&&, const MediaConstraints*); WEBCORE_EXPORT static AudioCaptureFactory& factory(); const RealtimeMediaSourceCapabilities& capabilities() override; @@ -42,7 +42,7 @@ class GStreamerAudioCaptureSource : public RealtimeMediaSource { GStreamerCapturer* capturer() { return m_capturer.get(); } protected: - GStreamerAudioCaptureSource(GStreamerCaptureDevice, String&& hashSalt); + GStreamerAudioCaptureSource(GStreamerCaptureDevice, MediaDeviceHashSalts&&); virtual ~GStreamerAudioCaptureSource(); void startProducingData() override; void stopProducingData() override; diff --git a/Source/WebCore/platform/mediastream/gstreamer/GStreamerCaptureDeviceManager.h b/Source/WebCore/platform/mediastream/gstreamer/GStreamerCaptureDeviceManager.h index 1a9f12333de4..c4c21e53463a 100644 --- a/Source/WebCore/platform/mediastream/gstreamer/GStreamerCaptureDeviceManager.h +++ b/Source/WebCore/platform/mediastream/gstreamer/GStreamerCaptureDeviceManager.h @@ -75,7 +75,7 @@ class GStreamerDisplayCaptureDeviceManager final : public DisplayCaptureManager static GStreamerDisplayCaptureDeviceManager& singleton(); const Vector& captureDevices() final { return m_devices; }; void computeCaptureDevices(CompletionHandler&&) final; - CaptureSourceOrError createDisplayCaptureSource(const CaptureDevice&, String&&, const MediaConstraints*); + CaptureSourceOrError createDisplayCaptureSource(const CaptureDevice&, MediaDeviceHashSalts&&, const MediaConstraints*); enum PipeWireOutputType { Monitor = 1 << 0, diff --git a/Source/WebCore/platform/mediastream/gstreamer/GStreamerDisplayCaptureDeviceManager.cpp b/Source/WebCore/platform/mediastream/gstreamer/GStreamerDisplayCaptureDeviceManager.cpp index bf4bb1057614..8a49228035f6 100644 --- a/Source/WebCore/platform/mediastream/gstreamer/GStreamerDisplayCaptureDeviceManager.cpp +++ b/Source/WebCore/platform/mediastream/gstreamer/GStreamerDisplayCaptureDeviceManager.cpp @@ -59,12 +59,12 @@ void GStreamerDisplayCaptureDeviceManager::computeCaptureDevices(CompletionHandl callback(); } -CaptureSourceOrError GStreamerDisplayCaptureDeviceManager::createDisplayCaptureSource(const CaptureDevice& device, String&& hashSalt, const MediaConstraints* constraints) +CaptureSourceOrError GStreamerDisplayCaptureDeviceManager::createDisplayCaptureSource(const CaptureDevice& device, MediaDeviceHashSalts&& hashSalts, const MediaConstraints* constraints) { const auto it = m_sessions.find(device.persistentId()); if (it != m_sessions.end()) { return GStreamerVideoCaptureSource::createPipewireSource(device.persistentId().isolatedCopy(), - it->value->nodeAndFd, WTFMove(hashSalt), constraints, device.type()); + it->value->nodeAndFd, WTFMove(hashSalts), constraints, device.type()); } GUniqueOutPtr error; @@ -188,7 +188,7 @@ CaptureSourceOrError GStreamerDisplayCaptureDeviceManager::createDisplayCaptureS NodeAndFD nodeAndFd = { *nodeId, fd }; auto session = makeUnique(nodeAndFd, WTFMove(sessionPath)); m_sessions.add(device.persistentId(), WTFMove(session)); - return GStreamerVideoCaptureSource::createPipewireSource(device.persistentId().isolatedCopy(), nodeAndFd, WTFMove(hashSalt), constraints, device.type()); + return GStreamerVideoCaptureSource::createPipewireSource(device.persistentId().isolatedCopy(), nodeAndFd, WTFMove(hashSalts), constraints, device.type()); } void GStreamerDisplayCaptureDeviceManager::stopSource(const String& persistentID) diff --git a/Source/WebCore/platform/mediastream/gstreamer/GStreamerVideoCaptureSource.cpp b/Source/WebCore/platform/mediastream/gstreamer/GStreamerVideoCaptureSource.cpp index 8b76ecac0c98..ff293a32e465 100644 --- a/Source/WebCore/platform/mediastream/gstreamer/GStreamerVideoCaptureSource.cpp +++ b/Source/WebCore/platform/mediastream/gstreamer/GStreamerVideoCaptureSource.cpp @@ -61,9 +61,9 @@ class GStreamerVideoPreset : public VideoPreset { class GStreamerVideoCaptureSourceFactory final : public VideoCaptureFactory { public: - CaptureSourceOrError createVideoCaptureSource(const CaptureDevice& device, String&& hashSalt, const MediaConstraints* constraints, PageIdentifier) final + CaptureSourceOrError createVideoCaptureSource(const CaptureDevice& device, MediaDeviceHashSalts&& hashSalts, const MediaConstraints* constraints, PageIdentifier) final { - return GStreamerVideoCaptureSource::create(String { device.persistentId() }, WTFMove(hashSalt), constraints); + return GStreamerVideoCaptureSource::create(String { device.persistentId() }, WTFMove(hashSalts), constraints); } private: CaptureDeviceManager& videoCaptureDeviceManager() final { return GStreamerVideoCaptureDeviceManager::singleton(); } @@ -71,16 +71,16 @@ class GStreamerVideoCaptureSourceFactory final : public VideoCaptureFactory { class GStreamerDisplayCaptureSourceFactory final : public DisplayCaptureFactory { public: - CaptureSourceOrError createDisplayCaptureSource(const CaptureDevice& device, String&& hashSalt, const MediaConstraints* constraints, PageIdentifier) final + CaptureSourceOrError createDisplayCaptureSource(const CaptureDevice& device, MediaDeviceHashSalts&& hashSalts, const MediaConstraints* constraints, PageIdentifier) final { auto& manager = GStreamerDisplayCaptureDeviceManager::singleton(); - return manager.createDisplayCaptureSource(device, WTFMove(hashSalt), constraints); + return manager.createDisplayCaptureSource(device, WTFMove(hashSalts), constraints); } private: DisplayCaptureManager& displayCaptureDeviceManager() final { return GStreamerDisplayCaptureDeviceManager::singleton(); } }; -CaptureSourceOrError GStreamerVideoCaptureSource::create(String&& deviceID, String&& hashSalt, const MediaConstraints* constraints) +CaptureSourceOrError GStreamerVideoCaptureSource::create(String&& deviceID, MediaDeviceHashSalts&& hashSalts, const MediaConstraints* constraints) { auto device = GStreamerVideoCaptureDeviceManager::singleton().gstreamerDeviceWithUID(deviceID); if (!device) { @@ -88,7 +88,7 @@ CaptureSourceOrError GStreamerVideoCaptureSource::create(String&& deviceID, Stri return CaptureSourceOrError(WTFMove(errorMessage)); } - auto source = adoptRef(*new GStreamerVideoCaptureSource(device.value(), WTFMove(hashSalt))); + auto source = adoptRef(*new GStreamerVideoCaptureSource(device.value(), WTFMove(hashSalts))); if (constraints) { if (auto result = source->applyConstraints(*constraints)) return WTFMove(result->badConstraint); @@ -96,9 +96,9 @@ CaptureSourceOrError GStreamerVideoCaptureSource::create(String&& deviceID, Stri return CaptureSourceOrError(WTFMove(source)); } -CaptureSourceOrError GStreamerVideoCaptureSource::createPipewireSource(String&& deviceID, const NodeAndFD& nodeAndFd, String&& hashSalt, const MediaConstraints* constraints, CaptureDevice::DeviceType deviceType) +CaptureSourceOrError GStreamerVideoCaptureSource::createPipewireSource(String&& deviceID, const NodeAndFD& nodeAndFd, MediaDeviceHashSalts&& hashSalts, const MediaConstraints* constraints, CaptureDevice::DeviceType deviceType) { - auto source = adoptRef(*new GStreamerVideoCaptureSource(WTFMove(deviceID), { }, WTFMove(hashSalt), "pipewiresrc", deviceType, nodeAndFd)); + auto source = adoptRef(*new GStreamerVideoCaptureSource(WTFMove(deviceID), { }, WTFMove(hashSalts), "pipewiresrc", deviceType, nodeAndFd)); if (constraints) { if (auto result = source->applyConstraints(*constraints)) return WTFMove(result->badConstraint); @@ -118,8 +118,8 @@ DisplayCaptureFactory& GStreamerVideoCaptureSource::displayFactory() return factory.get(); } -GStreamerVideoCaptureSource::GStreamerVideoCaptureSource(String&& deviceID, AtomString&& name, String&& hashSalt, const gchar* sourceFactory, CaptureDevice::DeviceType deviceType, const NodeAndFD& nodeAndFd) - : RealtimeVideoCaptureSource(WTFMove(name), WTFMove(deviceID), WTFMove(hashSalt), { }) +GStreamerVideoCaptureSource::GStreamerVideoCaptureSource(String&& deviceID, AtomString&& name, MediaDeviceHashSalts&& hashSalts, const gchar* sourceFactory, CaptureDevice::DeviceType deviceType, const NodeAndFD& nodeAndFd) + : RealtimeVideoCaptureSource(CaptureDevice { WTFMove(deviceID), CaptureDevice::DeviceType::Camera, WTFMove(name) }, WTFMove(hashSalts), { }) , m_capturer(makeUnique(sourceFactory, deviceType)) , m_deviceType(deviceType) { @@ -128,8 +128,8 @@ GStreamerVideoCaptureSource::GStreamerVideoCaptureSource(String&& deviceID, Atom m_capturer->addObserver(*this); } -GStreamerVideoCaptureSource::GStreamerVideoCaptureSource(GStreamerCaptureDevice device, String&& hashSalt) - : RealtimeVideoCaptureSource(AtomString { device.persistentId() }, String { device.label() }, WTFMove(hashSalt), { }) +GStreamerVideoCaptureSource::GStreamerVideoCaptureSource(GStreamerCaptureDevice device, MediaDeviceHashSalts&& hashSalts) + : RealtimeVideoCaptureSource(device, WTFMove(hashSalts), { }) , m_capturer(makeUnique(device)) , m_deviceType(CaptureDevice::DeviceType::Camera) { diff --git a/Source/WebCore/platform/mediastream/gstreamer/GStreamerVideoCaptureSource.h b/Source/WebCore/platform/mediastream/gstreamer/GStreamerVideoCaptureSource.h index 2ed5d04bdad7..ca14070510ea 100644 --- a/Source/WebCore/platform/mediastream/gstreamer/GStreamerVideoCaptureSource.h +++ b/Source/WebCore/platform/mediastream/gstreamer/GStreamerVideoCaptureSource.h @@ -34,8 +34,8 @@ using NodeAndFD = GStreamerVideoCapturer::NodeAndFD; class GStreamerVideoCaptureSource : public RealtimeVideoCaptureSource, GStreamerCapturer::Observer { public: - static CaptureSourceOrError create(String&& deviceID, String&& hashSalt, const MediaConstraints*); - static CaptureSourceOrError createPipewireSource(String&& deviceID, const NodeAndFD&, String&& hashSalt, const MediaConstraints*, CaptureDevice::DeviceType); + static CaptureSourceOrError create(String&& deviceID, MediaDeviceHashSalts&&, const MediaConstraints*); + static CaptureSourceOrError createPipewireSource(String&& deviceID, const NodeAndFD&, MediaDeviceHashSalts&&, const MediaConstraints*, CaptureDevice::DeviceType); WEBCORE_EXPORT static VideoCaptureFactory& factory(); @@ -51,8 +51,8 @@ class GStreamerVideoCaptureSource : public RealtimeVideoCaptureSource, GStreamer void sourceCapsChanged(const GstCaps*) final; protected: - GStreamerVideoCaptureSource(String&& deviceID, AtomString&& name, String&& hashSalt, const gchar* source_factory, CaptureDevice::DeviceType, const NodeAndFD&); - GStreamerVideoCaptureSource(GStreamerCaptureDevice, String&& hashSalt); + GStreamerVideoCaptureSource(String&& deviceID, AtomString&& name, MediaDeviceHashSalts&&, const gchar* source_factory, CaptureDevice::DeviceType, const NodeAndFD&); + GStreamerVideoCaptureSource(GStreamerCaptureDevice, MediaDeviceHashSalts&&); virtual ~GStreamerVideoCaptureSource(); void startProducingData() override; void stopProducingData() override; diff --git a/Source/WebCore/platform/mediastream/gstreamer/MockRealtimeAudioSourceGStreamer.cpp b/Source/WebCore/platform/mediastream/gstreamer/MockRealtimeAudioSourceGStreamer.cpp index 93c731428f0f..f49ebff52245 100644 --- a/Source/WebCore/platform/mediastream/gstreamer/MockRealtimeAudioSourceGStreamer.cpp +++ b/Source/WebCore/platform/mediastream/gstreamer/MockRealtimeAudioSourceGStreamer.cpp @@ -50,7 +50,7 @@ const HashSet& MockRealtimeAudioSourceGStreamer::allMo return allMockRealtimeAudioSourcesStorage(); } -CaptureSourceOrError MockRealtimeAudioSource::create(String&& deviceID, AtomString&& name, String&& hashSalt, const MediaConstraints* constraints, PageIdentifier) +CaptureSourceOrError MockRealtimeAudioSource::create(String&& deviceID, AtomString&& name, MediaDeviceHashSalts&& hashSalts, const MediaConstraints* constraints, PageIdentifier) { #ifndef NDEBUG auto device = MockRealtimeMediaSourceCenter::mockDeviceWithPersistentID(deviceID); @@ -59,7 +59,7 @@ CaptureSourceOrError MockRealtimeAudioSource::create(String&& deviceID, AtomStri return { "No mock microphone device"_s }; #endif - auto source = adoptRef(*new MockRealtimeAudioSourceGStreamer(WTFMove(deviceID), WTFMove(name), WTFMove(hashSalt))); + auto source = adoptRef(*new MockRealtimeAudioSourceGStreamer(WTFMove(deviceID), WTFMove(name), WTFMove(hashSalts))); if (constraints) { if (auto error = source->applyConstraints(*constraints)) return WTFMove(error->message); @@ -68,13 +68,13 @@ CaptureSourceOrError MockRealtimeAudioSource::create(String&& deviceID, AtomStri return CaptureSourceOrError(WTFMove(source)); } -Ref MockRealtimeAudioSourceGStreamer::createForMockAudioCapturer(String&& deviceID, AtomString&& name, String&& hashSalt) +Ref MockRealtimeAudioSourceGStreamer::createForMockAudioCapturer(String&& deviceID, AtomString&& name, MediaDeviceHashSalts&& hashSalts) { - return adoptRef(*new MockRealtimeAudioSourceGStreamer(WTFMove(deviceID), WTFMove(name), WTFMove(hashSalt))); + return adoptRef(*new MockRealtimeAudioSourceGStreamer(WTFMove(deviceID), WTFMove(name), WTFMove(hashSalts))); } -MockRealtimeAudioSourceGStreamer::MockRealtimeAudioSourceGStreamer(String&& deviceID, AtomString&& name, String&& hashSalt) - : MockRealtimeAudioSource(WTFMove(deviceID), WTFMove(name), WTFMove(hashSalt), { }) +MockRealtimeAudioSourceGStreamer::MockRealtimeAudioSourceGStreamer(String&& deviceID, AtomString&& name, MediaDeviceHashSalts&& hashSalts) + : MockRealtimeAudioSource(WTFMove(deviceID), WTFMove(name), WTFMove(hashSalts), { }) { ensureGStreamerInitialized(); allMockRealtimeAudioSourcesStorage().add(this); diff --git a/Source/WebCore/platform/mediastream/gstreamer/MockRealtimeAudioSourceGStreamer.h b/Source/WebCore/platform/mediastream/gstreamer/MockRealtimeAudioSourceGStreamer.h index 4b56702cb2d6..cff54a0b4fe0 100644 --- a/Source/WebCore/platform/mediastream/gstreamer/MockRealtimeAudioSourceGStreamer.h +++ b/Source/WebCore/platform/mediastream/gstreamer/MockRealtimeAudioSourceGStreamer.h @@ -32,7 +32,7 @@ namespace WebCore { class MockRealtimeAudioSourceGStreamer final : public MockRealtimeAudioSource { public: - static Ref createForMockAudioCapturer(String&& deviceID, AtomString&& name, String&& hashSalt); + static Ref createForMockAudioCapturer(String&& deviceID, AtomString&& name, MediaDeviceHashSalts&&); static const HashSet& allMockRealtimeAudioSources(); @@ -43,7 +43,7 @@ class MockRealtimeAudioSourceGStreamer final : public MockRealtimeAudioSource { private: friend class MockRealtimeAudioSource; - MockRealtimeAudioSourceGStreamer(String&& deviceID, AtomString&& name, String&& hashSalt); + MockRealtimeAudioSourceGStreamer(String&& deviceID, AtomString&& name, MediaDeviceHashSalts&&); void reconfigure(); void addHum(float amplitude, float frequency, float sampleRate, uint64_t start, float *p, uint64_t count); diff --git a/Source/WebCore/platform/mediastream/gstreamer/MockRealtimeVideoSourceGStreamer.cpp b/Source/WebCore/platform/mediastream/gstreamer/MockRealtimeVideoSourceGStreamer.cpp index f501f75c51af..396a78456bae 100644 --- a/Source/WebCore/platform/mediastream/gstreamer/MockRealtimeVideoSourceGStreamer.cpp +++ b/Source/WebCore/platform/mediastream/gstreamer/MockRealtimeVideoSourceGStreamer.cpp @@ -32,7 +32,7 @@ namespace WebCore { -CaptureSourceOrError MockRealtimeVideoSource::create(String&& deviceID, AtomString&& name, String&& hashSalt, const MediaConstraints* constraints, PageIdentifier) +CaptureSourceOrError MockRealtimeVideoSource::create(String&& deviceID, AtomString&& name, MediaDeviceHashSalts&& hashSalts, const MediaConstraints* constraints, PageIdentifier) { #ifndef NDEBUG auto device = MockRealtimeMediaSourceCenter::mockDeviceWithPersistentID(deviceID); @@ -41,7 +41,7 @@ CaptureSourceOrError MockRealtimeVideoSource::create(String&& deviceID, AtomStri return { "No mock camera device"_s }; #endif - auto source = adoptRef(*new MockRealtimeVideoSourceGStreamer(WTFMove(deviceID), WTFMove(name), WTFMove(hashSalt))); + auto source = adoptRef(*new MockRealtimeVideoSourceGStreamer(WTFMove(deviceID), WTFMove(name), WTFMove(hashSalts))); if (constraints) { if (auto error = source->applyConstraints(*constraints)) return WTFMove(error.value().badConstraint); @@ -50,23 +50,23 @@ CaptureSourceOrError MockRealtimeVideoSource::create(String&& deviceID, AtomStri return CaptureSourceOrError(RealtimeVideoSource::create(WTFMove(source))); } -CaptureSourceOrError MockDisplayCaptureSourceGStreamer::create(const CaptureDevice& device, String&& hashSalt, const MediaConstraints* constraints) +CaptureSourceOrError MockDisplayCaptureSourceGStreamer::create(const CaptureDevice& device, MediaDeviceHashSalts&& hashSalts, const MediaConstraints* constraints) { - auto mockSource = adoptRef(*new MockRealtimeVideoSourceGStreamer(String { device.persistentId() }, AtomString { device.label() }, String { hashSalt })); + auto mockSource = adoptRef(*new MockRealtimeVideoSourceGStreamer(String { device.persistentId() }, AtomString { device.label() }, MediaDeviceHashSalts { hashSalts })); if (constraints) { if (auto error = mockSource->applyConstraints(*constraints)) return WTFMove(error.value().badConstraint); } - auto source = adoptRef(*new MockDisplayCaptureSourceGStreamer(RealtimeMediaSource::Type::Video, WTFMove(mockSource), WTFMove(hashSalt), device.type())); + auto source = adoptRef(*new MockDisplayCaptureSourceGStreamer(device, WTFMove(mockSource), WTFMove(hashSalts))); return CaptureSourceOrError(WTFMove(source)); } -MockDisplayCaptureSourceGStreamer::MockDisplayCaptureSourceGStreamer(RealtimeMediaSource::Type type, Ref&& source, String&& hashSalt, CaptureDevice::DeviceType deviceType) - : RealtimeMediaSource(type, AtomString { source->name().string().isolatedCopy() }, source->persistentID().isolatedCopy(), WTFMove(hashSalt)) +MockDisplayCaptureSourceGStreamer::MockDisplayCaptureSourceGStreamer(const CaptureDevice& device, Ref&& source, MediaDeviceHashSalts&& hashSalts) + : RealtimeMediaSource(device, WTFMove(hashSalts)) , m_source(WTFMove(source)) - , m_deviceType(deviceType) + , m_deviceType(device.type()) { m_source->addVideoFrameObserver(*this); } @@ -145,8 +145,8 @@ const RealtimeMediaSourceSettings& MockDisplayCaptureSourceGStreamer::settings() return m_currentSettings.value(); } -MockRealtimeVideoSourceGStreamer::MockRealtimeVideoSourceGStreamer(String&& deviceID, AtomString&& name, String&& hashSalt) - : MockRealtimeVideoSource(WTFMove(deviceID), WTFMove(name), WTFMove(hashSalt), { }) +MockRealtimeVideoSourceGStreamer::MockRealtimeVideoSourceGStreamer(String&& deviceID, AtomString&& name, MediaDeviceHashSalts&& hashSalts) + : MockRealtimeVideoSource(WTFMove(deviceID), WTFMove(name), WTFMove(hashSalts), { }) { ensureGStreamerInitialized(); } diff --git a/Source/WebCore/platform/mediastream/gstreamer/MockRealtimeVideoSourceGStreamer.h b/Source/WebCore/platform/mediastream/gstreamer/MockRealtimeVideoSourceGStreamer.h index ea42fe9e2f90..1c799efdd8ed 100644 --- a/Source/WebCore/platform/mediastream/gstreamer/MockRealtimeVideoSourceGStreamer.h +++ b/Source/WebCore/platform/mediastream/gstreamer/MockRealtimeVideoSourceGStreamer.h @@ -30,7 +30,7 @@ namespace WebCore { class MockRealtimeVideoSourceGStreamer final : public MockRealtimeVideoSource { public: - MockRealtimeVideoSourceGStreamer(String&& deviceID, AtomString&& name, String&& hashSalt); + MockRealtimeVideoSourceGStreamer(String&& deviceID, AtomString&& name, MediaDeviceHashSalts&&); ~MockRealtimeVideoSourceGStreamer() = default; private: @@ -42,7 +42,7 @@ class MockRealtimeVideoSourceGStreamer final : public MockRealtimeVideoSource { class MockDisplayCaptureSourceGStreamer final : public RealtimeMediaSource, RealtimeMediaSource::VideoFrameObserver { public: - static CaptureSourceOrError create(const CaptureDevice&, String&&, const MediaConstraints*); + static CaptureSourceOrError create(const CaptureDevice&, MediaDeviceHashSalts&&, const MediaConstraints*); void requestToEnd(Observer&) final; bool isProducingData() const final { return m_source->isProducingData(); } @@ -53,7 +53,7 @@ class MockDisplayCaptureSourceGStreamer final : public RealtimeMediaSource, Real void videoFrameAvailable(VideoFrame&, VideoFrameTimeMetadata) final; private: - MockDisplayCaptureSourceGStreamer(RealtimeMediaSource::Type, Ref&&, String&&, CaptureDevice::DeviceType); + MockDisplayCaptureSourceGStreamer(const CaptureDevice&, Ref&&, MediaDeviceHashSalts&&); ~MockDisplayCaptureSourceGStreamer(); void startProducingData() final { m_source->start(); } diff --git a/Source/WebCore/platform/mediastream/gstreamer/RealtimeIncomingAudioSourceGStreamer.cpp b/Source/WebCore/platform/mediastream/gstreamer/RealtimeIncomingAudioSourceGStreamer.cpp index b00c19ee8971..353b2135fed4 100644 --- a/Source/WebCore/platform/mediastream/gstreamer/RealtimeIncomingAudioSourceGStreamer.cpp +++ b/Source/WebCore/platform/mediastream/gstreamer/RealtimeIncomingAudioSourceGStreamer.cpp @@ -28,7 +28,7 @@ namespace WebCore { RealtimeIncomingAudioSourceGStreamer::RealtimeIncomingAudioSourceGStreamer(AtomString&& audioTrackId) - : RealtimeIncomingSourceGStreamer(RealtimeMediaSource::Type::Audio, WTFMove(audioTrackId)) + : RealtimeIncomingSourceGStreamer(CaptureDevice { WTFMove(audioTrackId), CaptureDevice::DeviceType::Microphone, emptyString() }) { start(); } diff --git a/Source/WebCore/platform/mediastream/gstreamer/RealtimeIncomingSourceGStreamer.cpp b/Source/WebCore/platform/mediastream/gstreamer/RealtimeIncomingSourceGStreamer.cpp index b9d8128b68b0..9cfe4e93978e 100644 --- a/Source/WebCore/platform/mediastream/gstreamer/RealtimeIncomingSourceGStreamer.cpp +++ b/Source/WebCore/platform/mediastream/gstreamer/RealtimeIncomingSourceGStreamer.cpp @@ -30,8 +30,8 @@ GST_DEBUG_CATEGORY_EXTERN(webkit_webrtc_endpoint_debug); namespace WebCore { -RealtimeIncomingSourceGStreamer::RealtimeIncomingSourceGStreamer(Type type, AtomString&& name) - : RealtimeMediaSource(type, WTFMove(name)) +RealtimeIncomingSourceGStreamer::RealtimeIncomingSourceGStreamer(const CaptureDevice& device) + : RealtimeMediaSource(device) { m_bin = gst_bin_new(nullptr); m_valve = gst_element_factory_make("valve", nullptr); diff --git a/Source/WebCore/platform/mediastream/gstreamer/RealtimeIncomingSourceGStreamer.h b/Source/WebCore/platform/mediastream/gstreamer/RealtimeIncomingSourceGStreamer.h index 8875b0e67776..ff6568dc3b15 100644 --- a/Source/WebCore/platform/mediastream/gstreamer/RealtimeIncomingSourceGStreamer.h +++ b/Source/WebCore/platform/mediastream/gstreamer/RealtimeIncomingSourceGStreamer.h @@ -34,7 +34,7 @@ class RealtimeIncomingSourceGStreamer : public RealtimeMediaSource { void handleUpstreamEvent(GRefPtr&&); protected: - RealtimeIncomingSourceGStreamer(Type, AtomString&& name); + RealtimeIncomingSourceGStreamer(const CaptureDevice&); void closeValve() const; void openValve() const; diff --git a/Source/WebCore/platform/mediastream/gstreamer/RealtimeIncomingVideoSourceGStreamer.cpp b/Source/WebCore/platform/mediastream/gstreamer/RealtimeIncomingVideoSourceGStreamer.cpp index e3133f800d09..c2da12436073 100644 --- a/Source/WebCore/platform/mediastream/gstreamer/RealtimeIncomingVideoSourceGStreamer.cpp +++ b/Source/WebCore/platform/mediastream/gstreamer/RealtimeIncomingVideoSourceGStreamer.cpp @@ -30,7 +30,7 @@ namespace WebCore { RealtimeIncomingVideoSourceGStreamer::RealtimeIncomingVideoSourceGStreamer(AtomString&& videoTrackId) - : RealtimeIncomingSourceGStreamer(RealtimeMediaSource::Type::Video, WTFMove(videoTrackId)) + : RealtimeIncomingSourceGStreamer(CaptureDevice { WTFMove(videoTrackId), CaptureDevice::DeviceType::Camera, emptyString() }) { RealtimeMediaSourceSupportedConstraints constraints; constraints.setSupportsWidth(true); diff --git a/Source/WebCore/platform/mediastream/ios/CoreAudioCaptureSourceIOS.h b/Source/WebCore/platform/mediastream/ios/CoreAudioCaptureSourceIOS.h index 5d130faaa57e..5df27924e547 100644 --- a/Source/WebCore/platform/mediastream/ios/CoreAudioCaptureSourceIOS.h +++ b/Source/WebCore/platform/mediastream/ios/CoreAudioCaptureSourceIOS.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Apple Inc. All rights reserved. + * Copyright (C) 2017-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 @@ -41,7 +41,7 @@ class CoreAudioCaptureSourceFactoryIOS final : public CoreAudioCaptureSourceFact ~CoreAudioCaptureSourceFactoryIOS(); private: - CaptureSourceOrError createAudioCaptureSource(const CaptureDevice&, String&&, const MediaConstraints*, PageIdentifier) final; + CaptureSourceOrError createAudioCaptureSource(const CaptureDevice&, MediaDeviceHashSalts&&, const MediaConstraints*, PageIdentifier) final; void addExtensiveObserver(ExtensiveObserver&) final; void removeExtensiveObserver(ExtensiveObserver&) final; diff --git a/Source/WebCore/platform/mediastream/ios/CoreAudioCaptureSourceIOS.mm b/Source/WebCore/platform/mediastream/ios/CoreAudioCaptureSourceIOS.mm index bb329fe0e1d8..d41ff45dee4e 100644 --- a/Source/WebCore/platform/mediastream/ios/CoreAudioCaptureSourceIOS.mm +++ b/Source/WebCore/platform/mediastream/ios/CoreAudioCaptureSourceIOS.mm @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Apple Inc. All rights reserved. + * Copyright (C) 2017-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 @@ -116,13 +116,13 @@ - (void)sessionMediaServicesWereReset:(NSNotification*)notification AVAudioSessionCaptureDeviceManager::singleton().disableAllDevicesQuery(); } -CaptureSourceOrError CoreAudioCaptureSourceFactoryIOS::createAudioCaptureSource(const CaptureDevice& device, String&& hashSalt, const MediaConstraints* constraints, PageIdentifier pageIdentifier) +CaptureSourceOrError CoreAudioCaptureSourceFactoryIOS::createAudioCaptureSource(const CaptureDevice& device, MediaDeviceHashSalts&& hashSalts, const MediaConstraints* constraints, PageIdentifier pageIdentifier) { // We enable exhaustive query to be sure to start capture with the right device. // FIXME: We should stop the auxiliary session after starting capture. if (m_observers.computesEmpty()) AVAudioSessionCaptureDeviceManager::singleton().enableAllDevicesQuery(); - return CoreAudioCaptureSource::create(String { device.persistentId() }, WTFMove(hashSalt), constraints, pageIdentifier); + return CoreAudioCaptureSource::create(String { device.persistentId() }, WTFMove(hashSalts), constraints, pageIdentifier); } } diff --git a/Source/WebCore/platform/mediastream/mac/AVCaptureDeviceManager.mm b/Source/WebCore/platform/mediastream/mac/AVCaptureDeviceManager.mm index ad64477db9ab..18fc46e08b18 100644 --- a/Source/WebCore/platform/mediastream/mac/AVCaptureDeviceManager.mm +++ b/Source/WebCore/platform/mediastream/mac/AVCaptureDeviceManager.mm @@ -95,16 +95,16 @@ inline static bool deviceIsAvailable(AVCaptureDevice *device) { ASSERT(!isMainThread()); auto* currentDevices = [PAL::getAVCaptureDeviceClass() devices]; - auto changedDevices = adoptNS([[NSMutableArray alloc] init]); + auto removedDevices = adoptNS([[NSMutableArray alloc] init]); for (AVCaptureDevice *cachedDevice in m_avCaptureDevices.get()) { if (![currentDevices containsObject:cachedDevice]) - [changedDevices addObject:cachedDevice]; + [removedDevices addObject:cachedDevice]; } - if ([changedDevices count]) { - for (AVCaptureDevice *device in changedDevices.get()) + if ([removedDevices count]) { + for (AVCaptureDevice *device in removedDevices.get()) [device removeObserver:m_objcObserver.get() forKeyPath:@"suspended"]; - [m_avCaptureDevices removeObjectsInArray:changedDevices.get()]; + [m_avCaptureDevices removeObjectsInArray:removedDevices.get()]; } for (AVCaptureDevice *device in currentDevices) { @@ -121,10 +121,17 @@ inline static bool deviceIsAvailable(AVCaptureDevice *device) } -static inline CaptureDevice toCaptureDevice(AVCaptureDevice *device) +static inline CaptureDevice toCaptureDevice(AVCaptureDevice *device, bool isDefault = false) { CaptureDevice captureDevice { device.uniqueID, CaptureDevice::DeviceType::Camera, device.localizedName }; captureDevice.setEnabled(deviceIsAvailable(device)); + captureDevice.setIsDefault(isDefault); + +#if HAVE(CONTINUITY_CAMEARA) + if ([PAL::getAVCaptureDeviceClass() respondsToSelector:@selector(systemPreferredCamera)] && [device respondsToSelector:@selector(isContinuityCamera)]) + captureDevice.setIsEphemeral(device.isContinuityCamera && [PAL::getAVCaptureDeviceClass() systemPreferredCamera] != device); +#endif + return captureDevice; } @@ -165,11 +172,9 @@ static inline bool isVideoDevice(AVCaptureDevice *device) } #endif - if (defaultVideoDevice) { - auto device = toCaptureDevice(defaultVideoDevice); - device.setIsDefault(true); - deviceList.append(WTFMove(device)); - } + if (defaultVideoDevice) + deviceList.append(toCaptureDevice(defaultVideoDevice, true)); + for (AVCaptureDevice *platformDevice in currentDevices) { if (isVideoDevice(platformDevice) && platformDevice.uniqueID != defaultVideoDevice.uniqueID) deviceList.append(toCaptureDevice(platformDevice)); diff --git a/Source/WebCore/platform/mediastream/mac/AVVideoCaptureSource.h b/Source/WebCore/platform/mediastream/mac/AVVideoCaptureSource.h index 580ccbbf5544..6ae81cfe37f9 100644 --- a/Source/WebCore/platform/mediastream/mac/AVVideoCaptureSource.h +++ b/Source/WebCore/platform/mediastream/mac/AVVideoCaptureSource.h @@ -54,7 +54,7 @@ class ImageTransferSessionVT; class AVVideoCaptureSource : public RealtimeVideoCaptureSource, private OrientationNotifier::Observer { public: - static CaptureSourceOrError create(const CaptureDevice&, String&& hashSalt, const MediaConstraints*, PageIdentifier); + static CaptureSourceOrError create(const CaptureDevice&, MediaDeviceHashSalts&&, const MediaConstraints*, PageIdentifier); WEBCORE_EXPORT static VideoCaptureFactory& factory(); @@ -70,7 +70,7 @@ class AVVideoCaptureSource : public RealtimeVideoCaptureSource, private Orientat void captureDeviceSuspendedDidChange(); private: - AVVideoCaptureSource(AVCaptureDevice*, const CaptureDevice&, String&& hashSalt, PageIdentifier); + AVVideoCaptureSource(AVCaptureDevice*, const CaptureDevice&, MediaDeviceHashSalts&&, PageIdentifier); virtual ~AVVideoCaptureSource(); void clearSession(); diff --git a/Source/WebCore/platform/mediastream/mac/AVVideoCaptureSource.mm b/Source/WebCore/platform/mediastream/mac/AVVideoCaptureSource.mm index 7a8405121abd..d740ffeec0ba 100644 --- a/Source/WebCore/platform/mediastream/mac/AVVideoCaptureSource.mm +++ b/Source/WebCore/platform/mediastream/mac/AVVideoCaptureSource.mm @@ -109,13 +109,13 @@ static dispatch_queue_t globaVideoCaptureSerialQueue() RetainPtr format; }; -CaptureSourceOrError AVVideoCaptureSource::create(const CaptureDevice& device, String&& hashSalt, const MediaConstraints* constraints, PageIdentifier pageIdentifier) +CaptureSourceOrError AVVideoCaptureSource::create(const CaptureDevice& device, MediaDeviceHashSalts&& hashSalts, const MediaConstraints* constraints, PageIdentifier pageIdentifier) { auto *avDevice = [PAL::getAVCaptureDeviceClass() deviceWithUniqueID:device.persistentId()]; if (!avDevice) return { "No AVVideoCaptureSource device"_s }; - auto source = adoptRef(*new AVVideoCaptureSource(avDevice, device, WTFMove(hashSalt), pageIdentifier)); + auto source = adoptRef(*new AVVideoCaptureSource(avDevice, device, WTFMove(hashSalts), pageIdentifier)); if (constraints) { auto result = source->applyConstraints(*constraints); if (result) @@ -125,8 +125,8 @@ static dispatch_queue_t globaVideoCaptureSerialQueue() return CaptureSourceOrError(RealtimeVideoSource::create(WTFMove(source))); } -AVVideoCaptureSource::AVVideoCaptureSource(AVCaptureDevice* avDevice, const CaptureDevice& device, String&& hashSalt, PageIdentifier pageIdentifier) - : RealtimeVideoCaptureSource(AtomString(device.label()), String(device.persistentId()), WTFMove(hashSalt), pageIdentifier) +AVVideoCaptureSource::AVVideoCaptureSource(AVCaptureDevice* avDevice, const CaptureDevice& device, MediaDeviceHashSalts&& hashSalts, PageIdentifier pageIdentifier) + : RealtimeVideoCaptureSource(device, WTFMove(hashSalts), pageIdentifier) , m_objcObserver(adoptNS([[WebCoreAVVideoCaptureSourceObserver alloc] initWithCallback:this])) , m_device(avDevice) , m_verifyCapturingTimer(*this, &AVVideoCaptureSource::verifyIsCapturing) diff --git a/Source/WebCore/platform/mediastream/mac/CoreAudioCaptureSource.cpp b/Source/WebCore/platform/mediastream/mac/CoreAudioCaptureSource.cpp index e6695509c1be..aaf707e7a502 100644 --- a/Source/WebCore/platform/mediastream/mac/CoreAudioCaptureSource.cpp +++ b/Source/WebCore/platform/mediastream/mac/CoreAudioCaptureSource.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017-2019 Apple Inc. All rights reserved. + * Copyright (C) 2017-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 @@ -79,7 +79,7 @@ static CaptureSourceOrError initializeCoreAudioCaptureSource(Reflabel() }, WTFMove(hashSalt), device->deviceID(), nullptr, pageIdentifier)); + auto source = adoptRef(*new CoreAudioCaptureSource(device.value(), device->deviceID(), WTFMove(hashSalts), nullptr, pageIdentifier)); #elif PLATFORM(IOS_FAMILY) auto device = AVAudioSessionCaptureDeviceManager::singleton().audioSessionDeviceWithUID(WTFMove(deviceID)); if (!device) return { "No AVAudioSessionCaptureDevice device"_s }; - auto source = adoptRef(*new CoreAudioCaptureSource(WTFMove(deviceID), AtomString { device->label() }, WTFMove(hashSalt), 0, nullptr, pageIdentifier)); + auto source = adoptRef(*new CoreAudioCaptureSource(device.value(), 0, WTFMove(hashSalts), nullptr, pageIdentifier)); #endif return initializeCoreAudioCaptureSource(WTFMove(source), constraints); } -CaptureSourceOrError CoreAudioCaptureSource::createForTesting(String&& deviceID, AtomString&& label, String&& hashSalt, const MediaConstraints* constraints, BaseAudioSharedUnit& overrideUnit, PageIdentifier pageIdentifier) +CaptureSourceOrError CoreAudioCaptureSource::createForTesting(String&& deviceID, AtomString&& label, MediaDeviceHashSalts&& hashSalts, const MediaConstraints* constraints, BaseAudioSharedUnit& overrideUnit, PageIdentifier pageIdentifier) { CoreAudioCaptureSourceFactory::singleton().setOverrideUnit(&overrideUnit); - auto source = adoptRef(*new CoreAudioCaptureSource(WTFMove(deviceID), WTFMove(label), WTFMove(hashSalt), 0, &overrideUnit, pageIdentifier)); + auto source = adoptRef(*new CoreAudioCaptureSource(CaptureDevice { WTFMove(deviceID), CaptureDevice::DeviceType::Microphone, WTFMove(label) }, 0, WTFMove(hashSalts), &overrideUnit, pageIdentifier)); return initializeCoreAudioCaptureSource(WTFMove(source), constraints); } @@ -201,8 +201,8 @@ void CoreAudioCaptureSourceFactory::whenAudioCaptureUnitIsNotRunning(Function& speakerDevices() const final; @@ -154,9 +154,9 @@ class CoreAudioCaptureSourceFactory : public AudioCaptureFactory, public AudioSe BaseAudioSharedUnit* m_overrideUnit { nullptr }; }; -inline CaptureSourceOrError CoreAudioCaptureSourceFactory::createAudioCaptureSource(const CaptureDevice& device, String&& hashSalt, const MediaConstraints* constraints, PageIdentifier pageIdentifier) +inline CaptureSourceOrError CoreAudioCaptureSourceFactory::createAudioCaptureSource(const CaptureDevice& device, MediaDeviceHashSalts&& hashSalts, const MediaConstraints* constraints, PageIdentifier pageIdentifier) { - return CoreAudioCaptureSource::create(String { device.persistentId() }, WTFMove(hashSalt), constraints, pageIdentifier); + return CoreAudioCaptureSource::create(String { device.persistentId() }, WTFMove(hashSalts), constraints, pageIdentifier); } } // namespace WebCore diff --git a/Source/WebCore/platform/mediastream/mac/MockAudioSharedUnit.mm b/Source/WebCore/platform/mediastream/mac/MockAudioSharedUnit.mm index 2bc159ccd22d..cd52a49190fd 100644 --- a/Source/WebCore/platform/mediastream/mac/MockAudioSharedUnit.mm +++ b/Source/WebCore/platform/mediastream/mac/MockAudioSharedUnit.mm @@ -86,7 +86,7 @@ static void addHum(float amplitude, float frequency, float sampleRate, uint64_t } } -CaptureSourceOrError MockRealtimeAudioSource::create(String&& deviceID, AtomString&& name, String&& hashSalt, const MediaConstraints* constraints, PageIdentifier pageIdentifier) +CaptureSourceOrError MockRealtimeAudioSource::create(String&& deviceID, AtomString&& name, MediaDeviceHashSalts&& hashSalts, const MediaConstraints* constraints, PageIdentifier pageIdentifier) { auto device = MockRealtimeMediaSourceCenter::mockDeviceWithPersistentID(deviceID); ASSERT(device); @@ -94,7 +94,7 @@ static void addHum(float amplitude, float frequency, float sampleRate, uint64_t return { "No mock microphone device"_s }; MockAudioSharedUnit::singleton().setCaptureDevice(String { deviceID }, 0); - return CoreAudioCaptureSource::createForTesting(WTFMove(deviceID), WTFMove(name), WTFMove(hashSalt), constraints, MockAudioSharedUnit::singleton(), pageIdentifier); + return CoreAudioCaptureSource::createForTesting(WTFMove(deviceID), WTFMove(name), WTFMove(hashSalts), constraints, MockAudioSharedUnit::singleton(), pageIdentifier); } class MockAudioSharedInternalUnitState : public ThreadSafeRefCounted { diff --git a/Source/WebCore/platform/mediastream/mac/MockRealtimeVideoSourceMac.h b/Source/WebCore/platform/mediastream/mac/MockRealtimeVideoSourceMac.h index eadfe685b0d3..a1617d9e550c 100644 --- a/Source/WebCore/platform/mediastream/mac/MockRealtimeVideoSourceMac.h +++ b/Source/WebCore/platform/mediastream/mac/MockRealtimeVideoSourceMac.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015-2018 Apple Inc. All rights reserved. + * Copyright (C) 2015-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 @@ -47,13 +47,13 @@ class ImageTransferSessionVT; class MockRealtimeVideoSourceMac final : public MockRealtimeVideoSource { public: - static Ref createForMockDisplayCapturer(String&& deviceID, AtomString&& name, String&& hashSalt, PageIdentifier); + static Ref createForMockDisplayCapturer(String&& deviceID, AtomString&& name, MediaDeviceHashSalts&&, PageIdentifier); ~MockRealtimeVideoSourceMac() = default; private: friend class MockRealtimeVideoSource; - MockRealtimeVideoSourceMac(String&& deviceID, AtomString&& name, String&& hashSalt, PageIdentifier); + MockRealtimeVideoSourceMac(String&& deviceID, AtomString&& name, MediaDeviceHashSalts&&, PageIdentifier); PlatformLayer* platformLayer() const; void updateSampleBuffer() final; diff --git a/Source/WebCore/platform/mediastream/mac/MockRealtimeVideoSourceMac.mm b/Source/WebCore/platform/mediastream/mac/MockRealtimeVideoSourceMac.mm index 2dfa337b1e3f..4011bcaebbdc 100644 --- a/Source/WebCore/platform/mediastream/mac/MockRealtimeVideoSourceMac.mm +++ b/Source/WebCore/platform/mediastream/mac/MockRealtimeVideoSourceMac.mm @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015-2018 Apple Inc. All rights reserved. + * Copyright (C) 2015-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 @@ -51,7 +51,7 @@ namespace WebCore { -CaptureSourceOrError MockRealtimeVideoSource::create(String&& deviceID, AtomString&& name, String&& hashSalt, const MediaConstraints* constraints, PageIdentifier pageIdentifier) +CaptureSourceOrError MockRealtimeVideoSource::create(String&& deviceID, AtomString&& name, MediaDeviceHashSalts&& hashSalts, const MediaConstraints* constraints, PageIdentifier pageIdentifier) { #ifndef NDEBUG auto device = MockRealtimeMediaSourceCenter::mockDeviceWithPersistentID(deviceID); @@ -60,7 +60,7 @@ return { "No mock camera device"_s }; #endif - auto source = adoptRef(*new MockRealtimeVideoSourceMac(WTFMove(deviceID), WTFMove(name), WTFMove(hashSalt), pageIdentifier)); + auto source = adoptRef(*new MockRealtimeVideoSourceMac(WTFMove(deviceID), WTFMove(name), WTFMove(hashSalts), pageIdentifier)); if (constraints) { if (auto error = source->applyConstraints(*constraints)) return WTFMove(error->message); @@ -69,13 +69,13 @@ return CaptureSourceOrError(RealtimeVideoSource::create(WTFMove(source))); } -Ref MockRealtimeVideoSourceMac::createForMockDisplayCapturer(String&& deviceID, AtomString&& name, String&& hashSalt, PageIdentifier pageIdentifier) +Ref MockRealtimeVideoSourceMac::createForMockDisplayCapturer(String&& deviceID, AtomString&& name, MediaDeviceHashSalts&& hashSalts, PageIdentifier pageIdentifier) { - return adoptRef(*new MockRealtimeVideoSourceMac(WTFMove(deviceID), WTFMove(name), WTFMove(hashSalt), pageIdentifier)); + return adoptRef(*new MockRealtimeVideoSourceMac(WTFMove(deviceID), WTFMove(name), WTFMove(hashSalts), pageIdentifier)); } -MockRealtimeVideoSourceMac::MockRealtimeVideoSourceMac(String&& deviceID, AtomString&& name, String&& hashSalt, PageIdentifier pageIdentifier) - : MockRealtimeVideoSource(WTFMove(deviceID), WTFMove(name), WTFMove(hashSalt), pageIdentifier) +MockRealtimeVideoSourceMac::MockRealtimeVideoSourceMac(String&& deviceID, AtomString&& name, MediaDeviceHashSalts&& hashSalts, PageIdentifier pageIdentifier) + : MockRealtimeVideoSource(WTFMove(deviceID), WTFMove(name), WTFMove(hashSalts), pageIdentifier) , m_workQueue(WorkQueue::create("MockRealtimeVideoSource Render Queue", WorkQueue::QOS::UserInteractive)) { } diff --git a/Source/WebCore/platform/mediastream/mac/RealtimeMediaSourceCenterMac.cpp b/Source/WebCore/platform/mediastream/mac/RealtimeMediaSourceCenterMac.cpp index cf00820a4488..480f783ddddf 100644 --- a/Source/WebCore/platform/mediastream/mac/RealtimeMediaSourceCenterMac.cpp +++ b/Source/WebCore/platform/mediastream/mac/RealtimeMediaSourceCenterMac.cpp @@ -45,10 +45,10 @@ namespace WebCore { class VideoCaptureSourceFactoryMac final : public VideoCaptureFactory { public: - CaptureSourceOrError createVideoCaptureSource(const CaptureDevice& device, String&& hashSalt, const MediaConstraints* constraints, PageIdentifier pageIdentifier) final + CaptureSourceOrError createVideoCaptureSource(const CaptureDevice& device, MediaDeviceHashSalts&& hashSalts, const MediaConstraints* constraints, PageIdentifier pageIdentifier) final { ASSERT(device.type() == CaptureDevice::DeviceType::Camera); - return AVVideoCaptureSource::create(device, WTFMove(hashSalt), constraints, pageIdentifier); + return AVVideoCaptureSource::create(device, WTFMove(hashSalts), constraints, pageIdentifier); } private: @@ -57,9 +57,9 @@ class VideoCaptureSourceFactoryMac final : public VideoCaptureFactory { class DisplayCaptureSourceFactoryMac final : public DisplayCaptureFactory { public: - CaptureSourceOrError createDisplayCaptureSource(const CaptureDevice& device, String&& hashSalt, const MediaConstraints* constraints, PageIdentifier pageIdentifier) final + CaptureSourceOrError createDisplayCaptureSource(const CaptureDevice& device, MediaDeviceHashSalts&& hashSalts, const MediaConstraints* constraints, PageIdentifier pageIdentifier) final { - return DisplayCaptureSourceCocoa::create(device, WTFMove(hashSalt), constraints, pageIdentifier); + return DisplayCaptureSourceCocoa::create(device, WTFMove(hashSalts), constraints, pageIdentifier); } private: DisplayCaptureManager& displayCaptureDeviceManager() { return DisplayCaptureManagerCocoa::singleton(); } diff --git a/Source/WebCore/platform/mock/MockMediaDevice.h b/Source/WebCore/platform/mock/MockMediaDevice.h index 85ace7ff8eaf..09cdb222f44c 100644 --- a/Source/WebCore/platform/mock/MockMediaDevice.h +++ b/Source/WebCore/platform/mock/MockMediaDevice.h @@ -168,14 +168,16 @@ struct MockMediaDevice { CaptureDevice captureDevice() const { if (isMicrophone()) - return CaptureDevice { persistentId, CaptureDevice::DeviceType::Microphone, label, persistentId, true }; + return CaptureDevice { persistentId, CaptureDevice::DeviceType::Microphone, label, persistentId, true, false, true, isEphemeral }; + if (isSpeaker()) - return CaptureDevice { persistentId, CaptureDevice::DeviceType::Speaker, label, speakerProperties()->relatedMicrophoneId, true }; + return CaptureDevice { persistentId, CaptureDevice::DeviceType::Speaker, label, speakerProperties()->relatedMicrophoneId, true, false, true, isEphemeral }; + if (isCamera()) - return CaptureDevice { persistentId, CaptureDevice::DeviceType::Camera, label, persistentId, true }; + return CaptureDevice { persistentId, CaptureDevice::DeviceType::Camera, label, persistentId, true, false, true, isEphemeral }; ASSERT(isDisplay()); - return CaptureDevice { persistentId, std::get(properties).type, label, emptyString(), true }; + return CaptureDevice { persistentId, std::get(properties).type, label, emptyString(), true, false, true, isEphemeral }; } CaptureDevice::DeviceType type() const @@ -201,6 +203,7 @@ struct MockMediaDevice { { encoder << persistentId; encoder << label; + encoder << isEphemeral; WTF::switchOn(properties, [&](const MockMicrophoneProperties& properties) { encoder << (uint8_t)1; encoder << properties; @@ -217,13 +220,13 @@ struct MockMediaDevice { } template - static std::optional decodeMockMediaDevice(Decoder& decoder, String&& persistentId, String&& label) + static std::optional decodeMockMediaDevice(Decoder& decoder, String&& persistentId, String&& label, bool isEphemeral) { std::optional properties; decoder >> properties; if (!properties) return std::nullopt; - return MockMediaDevice { WTFMove(persistentId), WTFMove(label), WTFMove(*properties) }; + return MockMediaDevice { WTFMove(persistentId), WTFMove(label), isEphemeral, WTFMove(*properties) }; } template @@ -239,6 +242,11 @@ struct MockMediaDevice { if (!label) return std::nullopt; + std::optional isEphemeral; + decoder >> isEphemeral; + if (!isEphemeral) + return std::nullopt; + std::optional index; decoder >> index; if (!index) @@ -246,19 +254,20 @@ struct MockMediaDevice { switch (*index) { case 1: - return decodeMockMediaDevice(decoder, WTFMove(*persistentId), WTFMove(*label)); + return decodeMockMediaDevice(decoder, WTFMove(*persistentId), WTFMove(*label), *isEphemeral); case 2: - return decodeMockMediaDevice(decoder, WTFMove(*persistentId), WTFMove(*label)); + return decodeMockMediaDevice(decoder, WTFMove(*persistentId), WTFMove(*label), *isEphemeral); case 3: - return decodeMockMediaDevice(decoder, WTFMove(*persistentId), WTFMove(*label)); + return decodeMockMediaDevice(decoder, WTFMove(*persistentId), WTFMove(*label), *isEphemeral); case 4: - return decodeMockMediaDevice(decoder, WTFMove(*persistentId), WTFMove(*label)); + return decodeMockMediaDevice(decoder, WTFMove(*persistentId), WTFMove(*label), *isEphemeral); } return std::nullopt; } String persistentId; String label; + bool isEphemeral; std::variant properties; }; diff --git a/Source/WebCore/platform/mock/MockRealtimeAudioSource.cpp b/Source/WebCore/platform/mock/MockRealtimeAudioSource.cpp index d7445d4a5f11..247123294502 100644 --- a/Source/WebCore/platform/mock/MockRealtimeAudioSource.cpp +++ b/Source/WebCore/platform/mock/MockRealtimeAudioSource.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015-2018 Apple Inc. All rights reserved. + * Copyright (C) 2015-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 @@ -53,7 +53,7 @@ namespace WebCore { #if !PLATFORM(MAC) && !PLATFORM(IOS_FAMILY) && !USE(GSTREAMER) -CaptureSourceOrError MockRealtimeAudioSource::create(String&& deviceID, String&& name, String&& hashSalt, const MediaConstraints* constraints, PageIdentifier) +CaptureSourceOrError MockRealtimeAudioSource::create(String&& deviceID, String&& name, MediaDeviceHashSalts&& hashSalts, const MediaConstraints* constraints, PageIdentifier) { #ifndef NDEBUG auto device = MockRealtimeMediaSourceCenter::mockDeviceWithPersistentID(deviceID); @@ -62,7 +62,7 @@ CaptureSourceOrError MockRealtimeAudioSource::create(String&& deviceID, String&& return { "No mock microphone device"_s }; #endif - auto source = adoptRef(*new MockRealtimeAudioSource(WTFMove(deviceID), WTFMove(name), WTFMove(hashSalt))); + auto source = adoptRef(*new MockRealtimeAudioSource(WTFMove(deviceID), WTFMove(name), WTFMove(hashSalts))); if (constraints && source->applyConstraints(*constraints)) return { }; @@ -70,8 +70,8 @@ CaptureSourceOrError MockRealtimeAudioSource::create(String&& deviceID, String&& } #endif -MockRealtimeAudioSource::MockRealtimeAudioSource(String&& deviceID, AtomString&& name, String&& hashSalt, PageIdentifier pageIdentifier) - : RealtimeMediaSource(RealtimeMediaSource::Type::Audio, WTFMove(name), WTFMove(deviceID), WTFMove(hashSalt), pageIdentifier) +MockRealtimeAudioSource::MockRealtimeAudioSource(String&& deviceID, AtomString&& name, MediaDeviceHashSalts&& hashSalts, PageIdentifier pageIdentifier) + : RealtimeMediaSource(CaptureDevice { WTFMove(deviceID), CaptureDevice::DeviceType::Microphone, WTFMove(name) }, WTFMove(hashSalts), pageIdentifier) , m_workQueue(WorkQueue::create("MockRealtimeAudioSource Render Queue")) , m_timer(RunLoop::current(), this, &MockRealtimeAudioSource::tick) { diff --git a/Source/WebCore/platform/mock/MockRealtimeAudioSource.h b/Source/WebCore/platform/mock/MockRealtimeAudioSource.h index df35020df196..8eb2f5b7e8d5 100644 --- a/Source/WebCore/platform/mock/MockRealtimeAudioSource.h +++ b/Source/WebCore/platform/mock/MockRealtimeAudioSource.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015-2018 Apple Inc. All rights reserved. + * Copyright (C) 2015-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 @@ -42,7 +42,7 @@ namespace WebCore { class MockRealtimeAudioSource : public RealtimeMediaSource { public: - static CaptureSourceOrError create(String&& deviceID, AtomString&& name, String&& hashSalt, const MediaConstraints*, PageIdentifier); + static CaptureSourceOrError create(String&& deviceID, AtomString&& name, MediaDeviceHashSalts&&, const MediaConstraints*, PageIdentifier); virtual ~MockRealtimeAudioSource(); static void setIsInterrupted(bool); @@ -50,7 +50,7 @@ class MockRealtimeAudioSource : public RealtimeMediaSource { WEBCORE_EXPORT void setChannelCount(unsigned); protected: - MockRealtimeAudioSource(String&& deviceID, AtomString&& name, String&& hashSalt, PageIdentifier); + MockRealtimeAudioSource(String&& deviceID, AtomString&& name, MediaDeviceHashSalts&&, PageIdentifier); virtual void render(Seconds) = 0; void settingsDidChange(OptionSet) override; diff --git a/Source/WebCore/platform/mock/MockRealtimeMediaSourceCenter.cpp b/Source/WebCore/platform/mock/MockRealtimeMediaSourceCenter.cpp index e1c41fef2841..1bba526feaa8 100644 --- a/Source/WebCore/platform/mock/MockRealtimeMediaSourceCenter.cpp +++ b/Source/WebCore/platform/mock/MockRealtimeMediaSourceCenter.cpp @@ -57,14 +57,14 @@ namespace WebCore { static inline Vector defaultDevices() { return Vector { - MockMediaDevice { "239c24b0-2b15-11e3-8224-0800200c9a66"_s, "Mock audio device 1"_s, MockMicrophoneProperties { 44100 } }, - MockMediaDevice { "239c24b1-2b15-11e3-8224-0800200c9a66"_s, "Mock audio device 2"_s, MockMicrophoneProperties { 48000 } }, + MockMediaDevice { "239c24b0-2b15-11e3-8224-0800200c9a66"_s, "Mock audio device 1"_s, false, MockMicrophoneProperties { 44100 } }, + MockMediaDevice { "239c24b1-2b15-11e3-8224-0800200c9a66"_s, "Mock audio device 2"_s, false, MockMicrophoneProperties { 48000 } }, - MockMediaDevice { "239c24b0-2b15-11e3-8224-0800200c9a67"_s, "Mock speaker device 1"_s, MockSpeakerProperties { "239c24b0-2b15-11e3-8224-0800200c9a66"_s, 44100 } }, - MockMediaDevice { "239c24b1-2b15-11e3-8224-0800200c9a67"_s, "Mock speaker device 2"_s, MockSpeakerProperties { "239c24b1-2b15-11e3-8224-0800200c9a66"_s, 48000 } }, - MockMediaDevice { "239c24b2-2b15-11e3-8224-0800200c9a67"_s, "Mock speaker device 3"_s, MockSpeakerProperties { String { }, 48000 } }, + MockMediaDevice { "239c24b0-2b15-11e3-8224-0800200c9a67"_s, "Mock speaker device 1"_s, false, MockSpeakerProperties { "239c24b0-2b15-11e3-8224-0800200c9a66"_s, 44100 } }, + MockMediaDevice { "239c24b1-2b15-11e3-8224-0800200c9a67"_s, "Mock speaker device 2"_s, false, MockSpeakerProperties { "239c24b1-2b15-11e3-8224-0800200c9a66"_s, 48000 } }, + MockMediaDevice { "239c24b2-2b15-11e3-8224-0800200c9a67"_s, "Mock speaker device 3"_s, false, MockSpeakerProperties { String { }, 48000 } }, - MockMediaDevice { "239c24b2-2b15-11e3-8224-0800200c9a66"_s, "Mock video device 1"_s, + MockMediaDevice { "239c24b2-2b15-11e3-8224-0800200c9a66"_s, "Mock video device 1"_s, false, MockCameraProperties { 30, RealtimeMediaSourceSettings::VideoFacingMode::User, { @@ -76,7 +76,7 @@ static inline Vector defaultDevices() Color::black, } }, - MockMediaDevice { "239c24b3-2b15-11e3-8224-0800200c9a66"_s, "Mock video device 2"_s, + MockMediaDevice { "239c24b3-2b15-11e3-8224-0800200c9a66"_s, "Mock video device 2"_s, false, MockCameraProperties { 15, RealtimeMediaSourceSettings::VideoFacingMode::Environment, { @@ -92,23 +92,23 @@ static inline Vector defaultDevices() Color::darkGray, } }, - MockMediaDevice { "SCREEN-1"_s, "Mock screen device 1"_s, MockDisplayProperties { CaptureDevice::DeviceType::Screen, Color::lightGray, { 1920, 1080 } } }, - MockMediaDevice { "SCREEN-2"_s, "Mock screen device 2"_s, MockDisplayProperties { CaptureDevice::DeviceType::Screen, Color::yellow, { 3840, 2160 } } }, + MockMediaDevice { "SCREEN-1"_s, "Mock screen device 1"_s, false, MockDisplayProperties { CaptureDevice::DeviceType::Screen, Color::lightGray, { 1920, 1080 } } }, + MockMediaDevice { "SCREEN-2"_s, "Mock screen device 2"_s, false, MockDisplayProperties { CaptureDevice::DeviceType::Screen, Color::yellow, { 3840, 2160 } } }, - MockMediaDevice { "WINDOW-1"_s, "Mock window device 1"_s, MockDisplayProperties { CaptureDevice::DeviceType::Window, SRGBA { 255, 241, 181 }, { 640, 480 } } }, - MockMediaDevice { "WINDOW-2"_s, "Mock window device 2"_s, MockDisplayProperties { CaptureDevice::DeviceType::Window, SRGBA { 255, 208, 181 }, { 1280, 600 } } }, + MockMediaDevice { "WINDOW-1"_s, "Mock window device 1"_s, false, MockDisplayProperties { CaptureDevice::DeviceType::Window, SRGBA { 255, 241, 181 }, { 640, 480 } } }, + MockMediaDevice { "WINDOW-2"_s, "Mock window device 2"_s, false, MockDisplayProperties { CaptureDevice::DeviceType::Window, SRGBA { 255, 208, 181 }, { 1280, 600 } } }, }; } class MockRealtimeVideoSourceFactory : public VideoCaptureFactory { public: - CaptureSourceOrError createVideoCaptureSource(const CaptureDevice& device, String&& hashSalt, const MediaConstraints* constraints, PageIdentifier pageIdentifier) final + CaptureSourceOrError createVideoCaptureSource(const CaptureDevice& device, MediaDeviceHashSalts&& hashSalts, const MediaConstraints* constraints, PageIdentifier pageIdentifier) final { ASSERT(device.type() == CaptureDevice::DeviceType::Camera); if (!MockRealtimeMediaSourceCenter::captureDeviceWithPersistentID(CaptureDevice::DeviceType::Camera, device.persistentId())) return { "Unable to find mock camera device with given persistentID"_s }; - return MockRealtimeVideoSource::create(String { device.persistentId() }, AtomString { device.label() }, WTFMove(hashSalt), constraints, pageIdentifier); + return MockRealtimeVideoSource::create(String { device.persistentId() }, AtomString { device.label() }, WTFMove(hashSalts), constraints, pageIdentifier); } private: @@ -136,7 +136,7 @@ class MockDisplayCapturer final : public DisplayCaptureSourceCocoa::Capturer { }; MockDisplayCapturer::MockDisplayCapturer(const CaptureDevice& device, PageIdentifier pageIdentifier) - : m_source(MockRealtimeVideoSourceMac::createForMockDisplayCapturer(String { device.persistentId() }, AtomString { device.label() }, String { }, pageIdentifier)) + : m_source(MockRealtimeVideoSourceMac::createForMockDisplayCapturer(String { device.persistentId() }, AtomString { device.label() }, MediaDeviceHashSalts { "persistent"_s, "ephemeral"_s }, pageIdentifier)) { } @@ -178,7 +178,7 @@ IntSize MockDisplayCapturer::intrinsicSize() const class MockRealtimeDisplaySourceFactory : public DisplayCaptureFactory { public: - CaptureSourceOrError createDisplayCaptureSource(const CaptureDevice& device, String&& hashSalt, const MediaConstraints* constraints, PageIdentifier pageIdentifier) final + CaptureSourceOrError createDisplayCaptureSource(const CaptureDevice& device, MediaDeviceHashSalts&& hashSalts, const MediaConstraints* constraints, PageIdentifier pageIdentifier) final { if (!MockRealtimeMediaSourceCenter::captureDeviceWithPersistentID(device.type(), device.persistentId())) return { "Unable to find mock display device with given persistentID"_s }; @@ -187,12 +187,12 @@ class MockRealtimeDisplaySourceFactory : public DisplayCaptureFactory { case CaptureDevice::DeviceType::Screen: case CaptureDevice::DeviceType::Window: #if PLATFORM(MAC) - return DisplayCaptureSourceCocoa::create(UniqueRef(makeUniqueRef(device, pageIdentifier)), device, WTFMove(hashSalt), constraints, pageIdentifier); + return DisplayCaptureSourceCocoa::create(UniqueRef(makeUniqueRef(device, pageIdentifier)), device, WTFMove(hashSalts), constraints, pageIdentifier); #elif USE(GSTREAMER) UNUSED_PARAM(pageIdentifier); - return MockDisplayCaptureSourceGStreamer::create(device, WTFMove(hashSalt), constraints); + return MockDisplayCaptureSourceGStreamer::create(device, WTFMove(hashSalts), constraints); #else - return MockRealtimeVideoSource::create(String { device.persistentId() }, AtomString { device.label() }, WTFMove(hashSalt), constraints, pageIdentifier); + return MockRealtimeVideoSource::create(String { device.persistentId() }, AtomString { device.label() }, WTFMove(hashSalts), constraints, pageIdentifier); #endif break; case CaptureDevice::DeviceType::Microphone: @@ -213,13 +213,13 @@ class MockRealtimeDisplaySourceFactory : public DisplayCaptureFactory { class MockRealtimeAudioSourceFactory final : public AudioCaptureFactory { public: - CaptureSourceOrError createAudioCaptureSource(const CaptureDevice& device, String&& hashSalt, const MediaConstraints* constraints, PageIdentifier pageIdentifier) final + CaptureSourceOrError createAudioCaptureSource(const CaptureDevice& device, MediaDeviceHashSalts&& hashSalts, const MediaConstraints* constraints, PageIdentifier pageIdentifier) final { ASSERT(device.type() == CaptureDevice::DeviceType::Microphone); if (!MockRealtimeMediaSourceCenter::captureDeviceWithPersistentID(CaptureDevice::DeviceType::Microphone, device.persistentId())) return { "Unable to find mock microphone device with given persistentID"_s }; - return MockRealtimeAudioSource::create(String { device.persistentId() }, AtomString { device.label() }, WTFMove(hashSalt), constraints, pageIdentifier); + return MockRealtimeAudioSource::create(String { device.persistentId() }, AtomString { device.label() }, WTFMove(hashSalts), constraints, pageIdentifier); } private: CaptureDeviceManager& audioCaptureDeviceManager() final { return MockRealtimeMediaSourceCenter::singleton().audioCaptureDeviceManager(); } @@ -300,6 +300,7 @@ static CaptureDevice toCaptureDevice(const MockMediaDevice& device) auto captureDevice = device.captureDevice(); captureDevice.setEnabled(true); captureDevice.setIsMockDevice(true); + return captureDevice; } @@ -377,6 +378,22 @@ void MockRealtimeMediaSourceCenter::removeDevice(const String& persistentId) RealtimeMediaSourceCenter::singleton().captureDevicesChanged(); } +void MockRealtimeMediaSourceCenter::setDeviceIsEphemeral(const String& persistentId, bool isEphemeral) +{ + ASSERT(!persistentId.isEmpty()); + + auto& map = deviceMap(); + auto iterator = map.find(persistentId); + if (iterator == map.end()) + return; + + MockMediaDevice device = iterator->value; + device.isEphemeral = isEphemeral; + + removeDevice(persistentId); + addDevice(device); +} + std::optional MockRealtimeMediaSourceCenter::mockDeviceWithPersistentID(const String& id) { ASSERT(!id.isEmpty()); diff --git a/Source/WebCore/platform/mock/MockRealtimeMediaSourceCenter.h b/Source/WebCore/platform/mock/MockRealtimeMediaSourceCenter.h index 4f545f1cd8f3..3636dbdf4160 100644 --- a/Source/WebCore/platform/mock/MockRealtimeMediaSourceCenter.h +++ b/Source/WebCore/platform/mock/MockRealtimeMediaSourceCenter.h @@ -45,7 +45,8 @@ class MockRealtimeMediaSourceCenter { WEBCORE_EXPORT static void setDevices(Vector&&); WEBCORE_EXPORT static void addDevice(const MockMediaDevice&); - WEBCORE_EXPORT static void removeDevice(const String& persistentId); + WEBCORE_EXPORT static void removeDevice(const String&); + WEBCORE_EXPORT static void setDeviceIsEphemeral(const String&, bool); WEBCORE_EXPORT static void resetDevices(); WEBCORE_EXPORT static void setMockCaptureDevicesInterrupted(bool isCameraInterrupted, bool isMicrophoneInterrupted); diff --git a/Source/WebCore/platform/mock/MockRealtimeVideoSource.cpp b/Source/WebCore/platform/mock/MockRealtimeVideoSource.cpp index 9a644336230a..08a3fbddf8f7 100644 --- a/Source/WebCore/platform/mock/MockRealtimeVideoSource.cpp +++ b/Source/WebCore/platform/mock/MockRealtimeVideoSource.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015-2018 Apple Inc. All rights reserved. + * Copyright (C) 2015-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 @@ -50,7 +50,7 @@ namespace WebCore { #if !PLATFORM(MAC) && !PLATFORM(IOS_FAMILY) && !USE(GSTREAMER) -CaptureSourceOrError MockRealtimeVideoSource::create(String&& deviceID, AtomString&& name, String&& hashSalt, const MediaConstraints* constraints, PageIdentifier pageIdentifier) +CaptureSourceOrError MockRealtimeVideoSource::create(String&& deviceID, AtomString&& name, MediaDeviceHashSalts&& hashSalts, const MediaConstraints* constraints, PageIdentifier pageIdentifier) { #ifndef NDEBUG auto device = MockRealtimeMediaSourceCenter::mockDeviceWithPersistentID(deviceID); @@ -59,7 +59,7 @@ CaptureSourceOrError MockRealtimeVideoSource::create(String&& deviceID, AtomStri return { "No mock camera device"_s }; #endif - auto source = adoptRef(*new MockRealtimeVideoSource(WTFMove(deviceID), WTFMove(name), WTFMove(hashSalt), pageIdentifier)); + auto source = adoptRef(*new MockRealtimeVideoSource(WTFMove(deviceID), WTFMove(name), WTFMove(hashSalts), pageIdentifier)); if (constraints && source->applyConstraints(*constraints)) return { }; @@ -73,8 +73,8 @@ static HashSet& allMockRealtimeVideoSource() return videoSources; } -MockRealtimeVideoSource::MockRealtimeVideoSource(String&& deviceID, AtomString&& name, String&& hashSalt, PageIdentifier pageIdentifier) - : RealtimeVideoCaptureSource(WTFMove(name), WTFMove(deviceID), WTFMove(hashSalt), pageIdentifier) +MockRealtimeVideoSource::MockRealtimeVideoSource(String&& deviceID, AtomString&& name, MediaDeviceHashSalts&& hashSalts, PageIdentifier pageIdentifier) + : RealtimeVideoCaptureSource(CaptureDevice { WTFMove(deviceID), CaptureDevice::DeviceType::Camera, WTFMove(name) }, WTFMove(hashSalts), pageIdentifier) , m_emitFrameTimer(RunLoop::current(), this, &MockRealtimeVideoSource::generateFrame) { allMockRealtimeVideoSource().add(this); diff --git a/Source/WebCore/platform/mock/MockRealtimeVideoSource.h b/Source/WebCore/platform/mock/MockRealtimeVideoSource.h index 62b6d30ac895..4223c6343dc6 100644 --- a/Source/WebCore/platform/mock/MockRealtimeVideoSource.h +++ b/Source/WebCore/platform/mock/MockRealtimeVideoSource.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015-2018 Apple Inc. All rights reserved. + * Copyright (C) 2015-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 @@ -48,7 +48,7 @@ class GraphicsContext; class MockRealtimeVideoSource : public RealtimeVideoCaptureSource, private OrientationNotifier::Observer { public: - static CaptureSourceOrError create(String&& deviceID, AtomString&& name, String&& hashSalt, const MediaConstraints*, PageIdentifier); + static CaptureSourceOrError create(String&& deviceID, AtomString&& name, MediaDeviceHashSalts&&, const MediaConstraints*, PageIdentifier); ~MockRealtimeVideoSource(); static void setIsInterrupted(bool); @@ -56,7 +56,7 @@ class MockRealtimeVideoSource : public RealtimeVideoCaptureSource, private Orien ImageBuffer* imageBuffer() const; protected: - MockRealtimeVideoSource(String&& deviceID, AtomString&& name, String&& hashSalt, PageIdentifier); + MockRealtimeVideoSource(String&& deviceID, AtomString&& name, MediaDeviceHashSalts&&, PageIdentifier); virtual void updateSampleBuffer() = 0; diff --git a/Source/WebKit/GPUProcess/GPUProcess.cpp b/Source/WebKit/GPUProcess/GPUProcess.cpp index ab7d5c99e9ed..ceea9af1f7c1 100644 --- a/Source/WebKit/GPUProcess/GPUProcess.cpp +++ b/Source/WebKit/GPUProcess/GPUProcess.cpp @@ -419,6 +419,11 @@ void GPUProcess::removeMockMediaDevice(const String& persistentId) MockRealtimeMediaSourceCenter::removeDevice(persistentId); } +void GPUProcess::setMockMediaDeviceIsEphemeral(const String& persistentId, bool isEphemeral) +{ + MockRealtimeMediaSourceCenter::setDeviceIsEphemeral(persistentId, isEphemeral); +} + void GPUProcess::resetMockMediaDevices() { MockRealtimeMediaSourceCenter::resetDevices(); diff --git a/Source/WebKit/GPUProcess/GPUProcess.h b/Source/WebKit/GPUProcess/GPUProcess.h index d4966d261cc6..f9be35d0b6f8 100644 --- a/Source/WebKit/GPUProcess/GPUProcess.h +++ b/Source/WebKit/GPUProcess/GPUProcess.h @@ -155,7 +155,8 @@ class GPUProcess : public AuxiliaryProcess, public ThreadSafeRefCounted&); void addMockMediaDevice(const WebCore::MockMediaDevice&); void clearMockMediaDevices(); - void removeMockMediaDevice(const String& persistentId); + void removeMockMediaDevice(const String&); + void setMockMediaDeviceIsEphemeral(const String&, bool); void resetMockMediaDevices(); void setMockCaptureDevicesInterrupted(bool isCameraInterrupted, bool isMicrophoneInterrupted); void triggerMockMicrophoneConfigurationChange(); diff --git a/Source/WebKit/GPUProcess/GPUProcess.messages.in b/Source/WebKit/GPUProcess/GPUProcess.messages.in index 4a5a80927e2e..76f4363f90fa 100644 --- a/Source/WebKit/GPUProcess/GPUProcess.messages.in +++ b/Source/WebKit/GPUProcess/GPUProcess.messages.in @@ -44,6 +44,7 @@ messages -> GPUProcess LegacyReceiver { AddMockMediaDevice(struct WebCore::MockMediaDevice device) ClearMockMediaDevices() RemoveMockMediaDevice(String persistentId) + SetMockMediaDeviceIsEphemeral(String persistentId, bool isEphemeral) ResetMockMediaDevices() SetMockCaptureDevicesInterrupted(bool isCameraInterrupted, bool isMicrophoneInterrupted) TriggerMockMicrophoneConfigurationChange() diff --git a/Source/WebKit/UIProcess/API/C/WKMockMediaDevice.cpp b/Source/WebKit/UIProcess/API/C/WKMockMediaDevice.cpp index 12552e7b0365..19dc9e734163 100644 --- a/Source/WebKit/UIProcess/API/C/WKMockMediaDevice.cpp +++ b/Source/WebKit/UIProcess/API/C/WKMockMediaDevice.cpp @@ -48,7 +48,7 @@ void WKAddMockMediaDevice(WKContextRef context, WKStringRef persistentId, WKStri else if (typeString != "microphone"_s) return; - toImpl(context)->addMockMediaDevice({ WebKit::toImpl(persistentId)->string(), WebKit::toImpl(label)->string(), WTFMove(properties) }); + toImpl(context)->addMockMediaDevice({ WebKit::toImpl(persistentId)->string(), WebKit::toImpl(label)->string(), false, WTFMove(properties) }); #endif } @@ -66,3 +66,8 @@ void WKResetMockMediaDevices(WKContextRef context) { toImpl(context)->resetMockMediaDevices(); } + +void WKSetMockMediaDeviceIsEphemeral(WKContextRef context, WKStringRef persistentId, bool isEphemeral) +{ + toImpl(context)->setMockMediaDeviceIsEphemeral(WebKit::toImpl(persistentId)->string(), isEphemeral); +} diff --git a/Source/WebKit/UIProcess/API/C/WKMockMediaDevice.h b/Source/WebKit/UIProcess/API/C/WKMockMediaDevice.h index f776d2817119..57dc7ac985ab 100644 --- a/Source/WebKit/UIProcess/API/C/WKMockMediaDevice.h +++ b/Source/WebKit/UIProcess/API/C/WKMockMediaDevice.h @@ -36,6 +36,7 @@ WK_EXPORT void WKAddMockMediaDevice(WKContextRef, WKStringRef persistentId, WKSt WK_EXPORT void WKClearMockMediaDevices(WKContextRef); WK_EXPORT void WKRemoveMockMediaDevice(WKContextRef, WKStringRef persistentId); WK_EXPORT void WKResetMockMediaDevices(WKContextRef); +WK_EXPORT void WKSetMockMediaDeviceIsEphemeral(WKContextRef, WKStringRef persistentId, bool isEphemeral); #ifdef __cplusplus } diff --git a/Source/WebKit/UIProcess/Cocoa/UserMediaCaptureManagerProxy.cpp b/Source/WebKit/UIProcess/Cocoa/UserMediaCaptureManagerProxy.cpp index 8c34e526b95f..b40161918099 100644 --- a/Source/WebKit/UIProcess/Cocoa/UserMediaCaptureManagerProxy.cpp +++ b/Source/WebKit/UIProcess/Cocoa/UserMediaCaptureManagerProxy.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017-2020 Apple Inc. All rights reserved. + * Copyright (C) 2017-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 @@ -267,9 +267,9 @@ UserMediaCaptureManagerProxy::~UserMediaCaptureManagerProxy() m_connectionProxy->removeMessageReceiver(Messages::UserMediaCaptureManagerProxy::messageReceiverName()); } -CaptureSourceOrError UserMediaCaptureManagerProxy::createMicrophoneSource(const CaptureDevice& device, String&& hashSalt, const MediaConstraints* mediaConstraints, PageIdentifier pageIdentifier) +CaptureSourceOrError UserMediaCaptureManagerProxy::createMicrophoneSource(const CaptureDevice& device, MediaDeviceHashSalts&& hashSalts, const MediaConstraints* mediaConstraints, PageIdentifier pageIdentifier) { - auto sourceOrError = RealtimeMediaSourceCenter::singleton().audioCaptureFactory().createAudioCaptureSource(device, WTFMove(hashSalt), mediaConstraints, pageIdentifier); + auto sourceOrError = RealtimeMediaSourceCenter::singleton().audioCaptureFactory().createAudioCaptureSource(device, WTFMove(hashSalts), mediaConstraints, pageIdentifier); if (!sourceOrError) return sourceOrError; @@ -298,7 +298,7 @@ static bool canCaptureFromMultipleCameras() #endif } -CaptureSourceOrError UserMediaCaptureManagerProxy::createCameraSource(const CaptureDevice& device, String&& hashSalt, const MediaConstraints* mediaConstraints, PageIdentifier pageIdentifier) +CaptureSourceOrError UserMediaCaptureManagerProxy::createCameraSource(const CaptureDevice& device, MediaDeviceHashSalts&& hashSalts, const MediaConstraints* mediaConstraints, PageIdentifier pageIdentifier) { auto& perPageSources = m_pageSources.ensure(pageIdentifier, [] { return PageSources { }; }).iterator->value; for (auto& cameraSource : perPageSources.cameraSources) { @@ -316,7 +316,7 @@ CaptureSourceOrError UserMediaCaptureManagerProxy::createCameraSource(const Capt } } - auto sourceOrError = RealtimeMediaSourceCenter::singleton().videoCaptureFactory().createVideoCaptureSource(device, WTFMove(hashSalt), mediaConstraints, pageIdentifier); + auto sourceOrError = RealtimeMediaSourceCenter::singleton().videoCaptureFactory().createVideoCaptureSource(device, WTFMove(hashSalts), mediaConstraints, pageIdentifier); if (!sourceOrError) return sourceOrError; @@ -334,7 +334,7 @@ CaptureSourceOrError UserMediaCaptureManagerProxy::createCameraSource(const Capt return source; } -void UserMediaCaptureManagerProxy::createMediaSourceForCaptureDeviceWithConstraints(RealtimeMediaSourceIdentifier id, const CaptureDevice& device, String&& hashSalt, const MediaConstraints& mediaConstraints, bool shouldUseGPUProcessRemoteFrames, PageIdentifier pageIdentifier, CreateSourceCallback&& completionHandler) +void UserMediaCaptureManagerProxy::createMediaSourceForCaptureDeviceWithConstraints(RealtimeMediaSourceIdentifier id, const CaptureDevice& device, WebCore::MediaDeviceHashSalts&& hashSalts, const MediaConstraints& mediaConstraints, bool shouldUseGPUProcessRemoteFrames, PageIdentifier pageIdentifier, CreateSourceCallback&& completionHandler) { if (!m_connectionProxy->willStartCapture(device.type())) return completionHandler(false, "Request is not allowed"_s, RealtimeMediaSourceSettings { }, { }, { }, { }, 0); @@ -344,14 +344,14 @@ void UserMediaCaptureManagerProxy::createMediaSourceForCaptureDeviceWithConstrai CaptureSourceOrError sourceOrError; switch (device.type()) { case WebCore::CaptureDevice::DeviceType::Microphone: - sourceOrError = createMicrophoneSource(device, WTFMove(hashSalt), constraints, pageIdentifier); + sourceOrError = createMicrophoneSource(device, WTFMove(hashSalts), constraints, pageIdentifier); break; case WebCore::CaptureDevice::DeviceType::Camera: - sourceOrError = createCameraSource(device, WTFMove(hashSalt), constraints, pageIdentifier); + sourceOrError = createCameraSource(device, WTFMove(hashSalts), constraints, pageIdentifier); break; case WebCore::CaptureDevice::DeviceType::Screen: case WebCore::CaptureDevice::DeviceType::Window: - sourceOrError = RealtimeMediaSourceCenter::singleton().displayCaptureFactory().createDisplayCaptureSource(device, WTFMove(hashSalt), constraints, pageIdentifier); + sourceOrError = RealtimeMediaSourceCenter::singleton().displayCaptureFactory().createDisplayCaptureSource(device, WTFMove(hashSalts), constraints, pageIdentifier); break; case WebCore::CaptureDevice::DeviceType::SystemAudio: case WebCore::CaptureDevice::DeviceType::Speaker: diff --git a/Source/WebKit/UIProcess/Cocoa/UserMediaCaptureManagerProxy.h b/Source/WebKit/UIProcess/Cocoa/UserMediaCaptureManagerProxy.h index 74595979eec4..7bd5c22a8abb 100644 --- a/Source/WebKit/UIProcess/Cocoa/UserMediaCaptureManagerProxy.h +++ b/Source/WebKit/UIProcess/Cocoa/UserMediaCaptureManagerProxy.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017-2020 Apple Inc. All rights reserved. + * Copyright (C) 2017-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 @@ -84,7 +84,7 @@ class UserMediaCaptureManagerProxy : private IPC::MessageReceiver { void didReceiveMessage(IPC::Connection&, IPC::Decoder&) final; using CreateSourceCallback = CompletionHandler&&, WebCore::IntSize, double)>; - void createMediaSourceForCaptureDeviceWithConstraints(WebCore::RealtimeMediaSourceIdentifier, const WebCore::CaptureDevice& deviceID, String&&, const WebCore::MediaConstraints&, bool shouldUseGPUProcessRemoteFrames, WebCore::PageIdentifier, CreateSourceCallback&&); + void createMediaSourceForCaptureDeviceWithConstraints(WebCore::RealtimeMediaSourceIdentifier, const WebCore::CaptureDevice& deviceID, WebCore::MediaDeviceHashSalts&&, const WebCore::MediaConstraints&, bool shouldUseGPUProcessRemoteFrames, WebCore::PageIdentifier, CreateSourceCallback&&); void startProducingData(WebCore::RealtimeMediaSourceIdentifier); void stopProducingData(WebCore::RealtimeMediaSourceIdentifier); void removeSource(WebCore::RealtimeMediaSourceIdentifier); @@ -94,8 +94,8 @@ class UserMediaCaptureManagerProxy : private IPC::MessageReceiver { void endProducingData(WebCore::RealtimeMediaSourceIdentifier); void setShouldApplyRotation(WebCore::RealtimeMediaSourceIdentifier, bool shouldApplyRotation); - WebCore::CaptureSourceOrError createMicrophoneSource(const WebCore::CaptureDevice&, String&& hashSalt, const WebCore::MediaConstraints*, WebCore::PageIdentifier); - WebCore::CaptureSourceOrError createCameraSource(const WebCore::CaptureDevice&, String&& hashSalt, const WebCore::MediaConstraints*, WebCore::PageIdentifier); + WebCore::CaptureSourceOrError createMicrophoneSource(const WebCore::CaptureDevice&, WebCore::MediaDeviceHashSalts&&, const WebCore::MediaConstraints*, WebCore::PageIdentifier); + WebCore::CaptureSourceOrError createCameraSource(const WebCore::CaptureDevice&, WebCore::MediaDeviceHashSalts&&, const WebCore::MediaConstraints*, WebCore::PageIdentifier); class SourceProxy; friend class SourceProxy; diff --git a/Source/WebKit/UIProcess/Cocoa/UserMediaCaptureManagerProxy.messages.in b/Source/WebKit/UIProcess/Cocoa/UserMediaCaptureManagerProxy.messages.in index 8902ac51ea9f..8ef19799893f 100644 --- a/Source/WebKit/UIProcess/Cocoa/UserMediaCaptureManagerProxy.messages.in +++ b/Source/WebKit/UIProcess/Cocoa/UserMediaCaptureManagerProxy.messages.in @@ -1,4 +1,4 @@ -# Copyright (C) 2017-2020 Apple Inc. All rights reserved. +# Copyright (C) 2017-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 @@ -24,7 +24,7 @@ #if ENABLE(MEDIA_STREAM) messages -> UserMediaCaptureManagerProxy NotRefCounted { - CreateMediaSourceForCaptureDeviceWithConstraints(WebCore::RealtimeMediaSourceIdentifier id, WebCore::CaptureDevice device, String hashSalt, struct WebCore::MediaConstraints constraints, bool shouldUseGPUProcessRemoteFrames, WebCore::PageIdentifier pageIdentifier) -> (bool success, String invalidConstraints, WebCore::RealtimeMediaSourceSettings settings, WebCore::RealtimeMediaSourceCapabilities capabilities, Vector presets, WebCore::IntSize size, double frameRate) Async + CreateMediaSourceForCaptureDeviceWithConstraints(WebCore::RealtimeMediaSourceIdentifier id, WebCore::CaptureDevice device, struct WebCore::MediaDeviceHashSalts hashSalts, struct WebCore::MediaConstraints constraints, bool shouldUseGPUProcessRemoteFrames, WebCore::PageIdentifier pageIdentifier) -> (bool success, String invalidConstraints, WebCore::RealtimeMediaSourceSettings settings, WebCore::RealtimeMediaSourceCapabilities capabilities, Vector presets, WebCore::IntSize size, double frameRate) Async StartProducingData(WebCore::RealtimeMediaSourceIdentifier id) StopProducingData(WebCore::RealtimeMediaSourceIdentifier id) RemoveSource(WebCore::RealtimeMediaSourceIdentifier id) diff --git a/Source/WebKit/UIProcess/GPU/GPUProcessProxy.cpp b/Source/WebKit/UIProcess/GPU/GPUProcessProxy.cpp index 06f651dd1b30..ed61b4c4a154 100644 --- a/Source/WebKit/UIProcess/GPU/GPUProcessProxy.cpp +++ b/Source/WebKit/UIProcess/GPU/GPUProcessProxy.cpp @@ -341,6 +341,11 @@ void GPUProcessProxy::removeMockMediaDevice(const String& persistentId) send(Messages::GPUProcess::RemoveMockMediaDevice { persistentId }, 0); } +void GPUProcessProxy::setMockMediaDeviceIsEphemeral(const String& persistentId, bool isEphemeral) +{ + send(Messages::GPUProcess::SetMockMediaDeviceIsEphemeral { persistentId, isEphemeral }, 0); +} + void GPUProcessProxy::resetMockMediaDevices() { send(Messages::GPUProcess::ResetMockMediaDevices { }, 0); diff --git a/Source/WebKit/UIProcess/GPU/GPUProcessProxy.h b/Source/WebKit/UIProcess/GPU/GPUProcessProxy.h index f9825e923e49..6125a260a0cf 100644 --- a/Source/WebKit/UIProcess/GPU/GPUProcessProxy.h +++ b/Source/WebKit/UIProcess/GPU/GPUProcessProxy.h @@ -85,6 +85,7 @@ class GPUProcessProxy final : public AuxiliaryProcessProxy, private ProcessThrot void addMockMediaDevice(const WebCore::MockMediaDevice&); void clearMockMediaDevices(); void removeMockMediaDevice(const String&); + void setMockMediaDeviceIsEphemeral(const String&, bool); void resetMockMediaDevices(); void setMockCaptureDevicesInterrupted(bool isCameraInterrupted, bool isMicrophoneInterrupted); void triggerMockMicrophoneConfigurationChange(); diff --git a/Source/WebKit/UIProcess/SpeechRecognitionRemoteRealtimeMediaSource.cpp b/Source/WebKit/UIProcess/SpeechRecognitionRemoteRealtimeMediaSource.cpp index 3c1566e64215..92e28bb18e3e 100644 --- a/Source/WebKit/UIProcess/SpeechRecognitionRemoteRealtimeMediaSource.cpp +++ b/Source/WebKit/UIProcess/SpeechRecognitionRemoteRealtimeMediaSource.cpp @@ -45,7 +45,7 @@ Ref SpeechRecognitionRemoteRealtimeMediaSource::cr } SpeechRecognitionRemoteRealtimeMediaSource::SpeechRecognitionRemoteRealtimeMediaSource(WebCore::RealtimeMediaSourceIdentifier identifier, SpeechRecognitionRemoteRealtimeMediaSourceManager& manager, const WebCore::CaptureDevice& captureDevice, WebCore::PageIdentifier pageIdentifier) -: WebCore::RealtimeMediaSource(WebCore::RealtimeMediaSource::Type::Audio, AtomString { captureDevice.label() }, String { captureDevice.persistentId() }, { }, pageIdentifier) + : WebCore::RealtimeMediaSource(captureDevice, { }, pageIdentifier) , m_identifier(identifier) , m_manager(manager) #if PLATFORM(COCOA) diff --git a/Source/WebKit/UIProcess/UserMediaPermissionRequestManagerProxy.cpp b/Source/WebKit/UIProcess/UserMediaPermissionRequestManagerProxy.cpp index 6fc07e599db9..e3b5a22eccd8 100644 --- a/Source/WebKit/UIProcess/UserMediaPermissionRequestManagerProxy.cpp +++ b/Source/WebKit/UIProcess/UserMediaPermissionRequestManagerProxy.cpp @@ -1,6 +1,6 @@ /* * Copyright (C) 2014 Igalia S.L. - * Copyright (C) 2016-2020 Apple Inc. All rights reserved. + * Copyright (C) 2016-2022 Apple Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -39,6 +39,7 @@ #include #include #include +#include #include #if ENABLE(GPU_PROCESS) @@ -299,7 +300,7 @@ void UserMediaPermissionRequestManagerProxy::finishGrantingRequest(UserMediaPerm #endif auto& request = strongRequest.get(); - m_page.sendWithAsyncReply(Messages::WebPage::UserMediaAccessWasGranted { request.userMediaID(), request.audioDevice(), request.videoDevice(), request.deviceIdentifierHashSalt(), handle }, [this, weakThis = WTFMove(weakThis)] { + m_page.sendWithAsyncReply(Messages::WebPage::UserMediaAccessWasGranted { request.userMediaID(), request.audioDevice(), request.videoDevice(), request.deviceIdentifierHashSalts(), handle }, [this, weakThis = WTFMove(weakThis)] { if (!weakThis) return; if (!--m_hasPendingCapture) @@ -310,6 +311,12 @@ void UserMediaPermissionRequestManagerProxy::finishGrantingRequest(UserMediaPerm }); } +void UserMediaPermissionRequestManagerProxy::didCommitLoadForFrame(FrameIdentifier frameID) +{ + ALWAYS_LOG(LOGIDENTIFIER, frameID.object().toUInt64()); + m_frameEphemeralHashSalts.remove(frameID); +} + void UserMediaPermissionRequestManagerProxy::resetAccess(std::optional frameID) { ALWAYS_LOG(LOGIDENTIFIER, frameID ? frameID->toUInt64() : 0); @@ -319,9 +326,11 @@ void UserMediaPermissionRequestManagerProxy::resetAccess(std::optionalmainFrameID() == frameID; }); m_grantedFrames.remove(*frameID); + m_frameEphemeralHashSalts.remove(*frameID); } else { m_grantedRequests.clear(); m_grantedFrames.clear(); + m_frameEphemeralHashSalts.clear(); } m_pregrantedRequests.clear(); m_deniedRequests.clear(); @@ -520,6 +529,30 @@ void UserMediaPermissionRequestManagerProxy::startProcessingUserMediaPermissionR }); } +String UserMediaPermissionRequestManagerProxy::ephemeralDeviceHashSaltForFrame(WebCore::FrameIdentifier frameIdentifier) +{ + auto iter = m_frameEphemeralHashSalts.find(frameIdentifier); + if (iter != m_frameEphemeralHashSalts.end()) + return iter->value; + + static constexpr unsigned hashSaltSize { 48 }; + static constexpr unsigned randomDataSize { hashSaltSize / 16 }; + + uint64_t randomData[randomDataSize]; + cryptographicallyRandomValues(reinterpret_cast(randomData), sizeof(randomData)); + + StringBuilder builder; + builder.reserveCapacity(hashSaltSize); + for (unsigned i = 0; i < randomDataSize; i++) + builder.append(hex(randomData[i])); + + auto hashSaltForFrame = builder.toString(); + auto firstAddResult = m_frameEphemeralHashSalts.add(frameIdentifier, hashSaltForFrame); + RELEASE_ASSERT(firstAddResult.isNewEntry); + + return hashSaltForFrame; +} + void UserMediaPermissionRequestManagerProxy::processUserMediaPermissionRequest() { ALWAYS_LOG(LOGIDENTIFIER, m_currentUserMediaRequest->userMediaID().toUInt64(), ", persistent access: ", m_currentUserMediaRequest->hasPersistentAccess()); @@ -540,26 +573,28 @@ void UserMediaPermissionRequestManagerProxy::processUserMediaPermissionRequest() processUserMediaPermissionInvalidRequest(invalidConstraint); }; - auto validHandler = [this, request](Vector&& audioDevices, Vector&& videoDevices, String&& deviceIdentifierHashSalt) mutable { + WebCore::MediaDeviceHashSalts deviceHashSaltsForFrame = { deviceIDHashSalt, ephemeralDeviceHashSaltForFrame(request->frameID()) }; + + auto validHandler = [this, request, deviceHashSaltsForFrame = deviceHashSaltsForFrame](Vector&& audioDevices, Vector&& videoDevices) mutable { if (!request->isPending()) return; if (!m_page.hasRunningProcess() || !m_page.mainFrame()) return; - processUserMediaPermissionValidRequest(WTFMove(audioDevices), WTFMove(videoDevices), WTFMove(deviceIdentifierHashSalt)); + processUserMediaPermissionValidRequest(WTFMove(audioDevices), WTFMove(videoDevices), WTFMove(deviceHashSaltsForFrame)); }; syncWithWebCorePrefs(); - platformValidateUserMediaRequestConstraints(WTFMove(validHandler), WTFMove(invalidHandler), WTFMove(deviceIDHashSalt)); + platformValidateUserMediaRequestConstraints(WTFMove(validHandler), WTFMove(invalidHandler), WTFMove(deviceHashSaltsForFrame)); }); } #if !USE(GLIB) -void UserMediaPermissionRequestManagerProxy::platformValidateUserMediaRequestConstraints(WebCore::RealtimeMediaSourceCenter::ValidConstraintsHandler&& validHandler, RealtimeMediaSourceCenter::InvalidConstraintsHandler&& invalidHandler, String&& deviceIDHashSalt) +void UserMediaPermissionRequestManagerProxy::platformValidateUserMediaRequestConstraints(WebCore::RealtimeMediaSourceCenter::ValidConstraintsHandler&& validHandler, RealtimeMediaSourceCenter::InvalidConstraintsHandler&& invalidHandler, MediaDeviceHashSalts&& deviceIDHashSalts) { - RealtimeMediaSourceCenter::singleton().validateRequestConstraints(WTFMove(validHandler), WTFMove(invalidHandler), m_currentUserMediaRequest->userRequest(), WTFMove(deviceIDHashSalt)); + RealtimeMediaSourceCenter::singleton().validateRequestConstraints(WTFMove(validHandler), WTFMove(invalidHandler), m_currentUserMediaRequest->userRequest(), WTFMove(deviceIDHashSalts)); } #endif @@ -571,7 +606,7 @@ void UserMediaPermissionRequestManagerProxy::processUserMediaPermissionInvalidRe denyRequest(*m_currentUserMediaRequest, UserMediaPermissionRequestProxy::UserMediaAccessDenialReason::InvalidConstraint, filterConstraint ? String { } : invalidConstraint); } -void UserMediaPermissionRequestManagerProxy::processUserMediaPermissionValidRequest(Vector&& audioDevices, Vector&& videoDevices, String&& deviceIdentifierHashSalt) +void UserMediaPermissionRequestManagerProxy::processUserMediaPermissionValidRequest(Vector&& audioDevices, Vector&& videoDevices, WebCore::MediaDeviceHashSalts&& deviceIdentifierHashSalts) { ALWAYS_LOG(LOGIDENTIFIER, m_currentUserMediaRequest->userMediaID().toUInt64(), ", video: ", videoDevices.size(), " audio: ", audioDevices.size()); if (videoDevices.isEmpty() && audioDevices.isEmpty()) { @@ -579,7 +614,7 @@ void UserMediaPermissionRequestManagerProxy::processUserMediaPermissionValidRequ return; } - m_currentUserMediaRequest->setDeviceIdentifierHashSalt(WTFMove(deviceIdentifierHashSalt)); + m_currentUserMediaRequest->setDeviceIdentifierHashSalts(WTFMove(deviceIdentifierHashSalts)); m_currentUserMediaRequest->setEligibleVideoDeviceUIDs(WTFMove(videoDevices)); m_currentUserMediaRequest->setEligibleAudioDeviceUIDs(WTFMove(audioDevices)); @@ -807,7 +842,7 @@ void UserMediaPermissionRequestManagerProxy::computeFilteredDeviceList(bool reve } #endif -void UserMediaPermissionRequestManagerProxy::enumerateMediaDevicesForFrame(FrameIdentifier frameID, Ref&& userMediaDocumentOrigin, Ref&& topLevelDocumentOrigin, CompletionHandler&, const String&)>&& completionHandler) +void UserMediaPermissionRequestManagerProxy::enumerateMediaDevicesForFrame(FrameIdentifier frameID, Ref&& userMediaDocumentOrigin, Ref&& topLevelDocumentOrigin, CompletionHandler&, MediaDeviceHashSalts&&)>&& completionHandler) { #if ENABLE(MEDIA_STREAM) ALWAYS_LOG(LOGIDENTIFIER); @@ -852,11 +887,12 @@ void UserMediaPermissionRequestManagerProxy::enumerateMediaDevicesForFrame(Frame syncWithWebCorePrefs(); + MediaDeviceHashSalts hashSaltsForRequest = { deviceIDHashSalt, ephemeralDeviceHashSaltForFrame(frameID) }; bool revealIdsAndLabels = originHasPersistentAccess || wasGrantedVideoOrAudioAccess(frameID); callCompletionHandler.release(); - computeFilteredDeviceList(revealIdsAndLabels, [completionHandler = WTFMove(completionHandler), deviceIDHashSalt = WTFMove(deviceIDHashSalt)] (auto&& devices) mutable { - completionHandler(devices, deviceIDHashSalt); + computeFilteredDeviceList(revealIdsAndLabels, [completionHandler = WTFMove(completionHandler), hashSaltsForRequest = WTFMove(hashSaltsForRequest)] (auto&& devices) mutable { + completionHandler(devices, WTFMove(hashSaltsForRequest)); }); }); }; diff --git a/Source/WebKit/UIProcess/UserMediaPermissionRequestManagerProxy.h b/Source/WebKit/UIProcess/UserMediaPermissionRequestManagerProxy.h index 903edb43333a..712cd380ed6d 100644 --- a/Source/WebKit/UIProcess/UserMediaPermissionRequestManagerProxy.h +++ b/Source/WebKit/UIProcess/UserMediaPermissionRequestManagerProxy.h @@ -1,6 +1,6 @@ /* * Copyright (C) 2014 Igalia S.L. - * Copyright (C) 2016-2020 Apple Inc. All rights reserved. + * Copyright (C) 2016-2022 Apple Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -78,12 +78,13 @@ class UserMediaPermissionRequestManagerProxy void requestUserMediaPermissionForFrame(WebCore::UserMediaRequestIdentifier, WebCore::FrameIdentifier, Ref&& userMediaDocumentOrigin, Ref&& topLevelDocumentOrigin, WebCore::MediaStreamRequest&&); void resetAccess(std::optional mainFrameID = { }); + void didCommitLoadForFrame(WebCore::FrameIdentifier); void viewIsBecomingVisible(); void grantRequest(UserMediaPermissionRequestProxy&); void denyRequest(UserMediaPermissionRequestProxy&, UserMediaPermissionRequestProxy::UserMediaAccessDenialReason, const String& invalidConstraint = { }); - void enumerateMediaDevicesForFrame(WebCore::FrameIdentifier, Ref&& userMediaDocumentOrigin, Ref&& topLevelDocumentOrigin, CompletionHandler&, const String&)>&&); + void enumerateMediaDevicesForFrame(WebCore::FrameIdentifier, Ref&& userMediaDocumentOrigin, Ref&& topLevelDocumentOrigin, CompletionHandler&, WebCore::MediaDeviceHashSalts&&)>&&); void stopCapture(); void scheduleNextRejection(); @@ -151,12 +152,12 @@ class UserMediaPermissionRequestManagerProxy void processUserMediaPermissionRequest(); void processUserMediaPermissionInvalidRequest(const String& invalidConstraint); - void processUserMediaPermissionValidRequest(Vector&& audioDevices, Vector&& videoDevices, String&& deviceIdentifierHashSalt); + void processUserMediaPermissionValidRequest(Vector&& audioDevices, Vector&& videoDevices, WebCore::MediaDeviceHashSalts&&); void startProcessingUserMediaPermissionRequest(Ref&&); static void requestSystemValidation(const WebPageProxy&, UserMediaPermissionRequestProxy&, CompletionHandler&&); - void platformValidateUserMediaRequestConstraints(WebCore::RealtimeMediaSourceCenter::ValidConstraintsHandler&& validHandler, WebCore::RealtimeMediaSourceCenter::InvalidConstraintsHandler&& invalidHandler, String&& deviceIDHashSalt); + void platformValidateUserMediaRequestConstraints(WebCore::RealtimeMediaSourceCenter::ValidConstraintsHandler&& validHandler, WebCore::RealtimeMediaSourceCenter::InvalidConstraintsHandler&& invalidHandler, WebCore::MediaDeviceHashSalts&&); #endif bool mockCaptureDevicesEnabled() const; @@ -167,6 +168,8 @@ class UserMediaPermissionRequestManagerProxy void decidePolicyForUserMediaPermissionRequest(); void updateStoredRequests(UserMediaPermissionRequestProxy&); + String ephemeralDeviceHashSaltForFrame(WebCore::FrameIdentifier); + RefPtr m_currentUserMediaRequest; Deque> m_pendingUserMediaRequests; HashSet m_pendingDeviceRequests; @@ -178,6 +181,7 @@ class UserMediaPermissionRequestManagerProxy Vector> m_pregrantedRequests; Vector> m_grantedRequests; + HashMap m_frameEphemeralHashSalts; Vector m_deniedRequests; diff --git a/Source/WebKit/UIProcess/UserMediaPermissionRequestProxy.h b/Source/WebKit/UIProcess/UserMediaPermissionRequestProxy.h index d7fb88998d97..3d2e88121d81 100644 --- a/Source/WebKit/UIProcess/UserMediaPermissionRequestProxy.h +++ b/Source/WebKit/UIProcess/UserMediaPermissionRequestProxy.h @@ -1,6 +1,6 @@ /* * Copyright (C) 2014 Igalia S.L. - * Copyright (C) 2016-2019 Apple Inc. All rights reserved. + * Copyright (C) 2016-2022 Apple Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -22,6 +22,7 @@ #include "APIObject.h" #include #include +#include #include #include #include @@ -86,8 +87,8 @@ class UserMediaPermissionRequestProxy : public API::ObjectImpl m_eligibleAudioDevices; WebCore::MediaStreamRequest m_request; bool m_hasPersistentAccess { false }; - String m_deviceIdentifierHashSalt; + WebCore::MediaDeviceHashSalts m_deviceIdentifierHashSalts; CompletionHandler m_decisionCompletionHandler; }; diff --git a/Source/WebKit/UIProcess/WebPageProxy.cpp b/Source/WebKit/UIProcess/WebPageProxy.cpp index 21c0134f6aaf..70d815ba966f 100644 --- a/Source/WebKit/UIProcess/WebPageProxy.cpp +++ b/Source/WebKit/UIProcess/WebPageProxy.cpp @@ -168,6 +168,7 @@ #include #include #include +#include #include #include #include @@ -5209,6 +5210,10 @@ void WebPageProxy::didCommitLoadForFrame(FrameIdentifier frameID, FrameInfoData& if (frame->isMainFrame() && m_preferences->mediaSessionCoordinatorEnabled()) GroupActivitiesSessionNotifier::sharedNotifier().webPageURLChanged(*this); #endif + +#if ENABLE(MEDIA_STREAM) + userMediaPermissionRequestManager().didCommitLoadForFrame(frameID); +#endif } void WebPageProxy::didFinishDocumentLoadForFrame(FrameIdentifier frameID, uint64_t navigationID, const UserData& userData) @@ -9003,7 +9008,7 @@ void WebPageProxy::requestUserMediaPermissionForFrame(UserMediaRequestIdentifier #endif } -void WebPageProxy::enumerateMediaDevicesForFrame(FrameIdentifier frameID, const WebCore::SecurityOriginData& userMediaDocumentOriginData, const WebCore::SecurityOriginData& topLevelDocumentOriginData, CompletionHandler&, const String&)>&& completionHandler) +void WebPageProxy::enumerateMediaDevicesForFrame(FrameIdentifier frameID, const WebCore::SecurityOriginData& userMediaDocumentOriginData, const WebCore::SecurityOriginData& topLevelDocumentOriginData, CompletionHandler&, WebCore::MediaDeviceHashSalts&&)>&& completionHandler) { #if ENABLE(MEDIA_STREAM) WebFrameProxy* frame = m_process->webFrame(frameID); diff --git a/Source/WebKit/UIProcess/WebPageProxy.h b/Source/WebKit/UIProcess/WebPageProxy.h index ffc044449f1e..d77d46b49429 100644 --- a/Source/WebKit/UIProcess/WebPageProxy.h +++ b/Source/WebKit/UIProcess/WebPageProxy.h @@ -115,6 +115,7 @@ #include #include #include +#include #include #include #include @@ -302,6 +303,7 @@ struct FileChooserSettings; struct GlobalWindowIdentifier; struct InteractionRegion; struct LinkIcon; +struct MediaDeviceHashSalts; struct MediaStreamRequest; struct MediaUsageInfo; struct MockWebAuthenticationConfiguration; @@ -2301,7 +2303,7 @@ class WebPageProxy final : public API::ObjectImpl UserMediaPermissionRequestManagerProxy& userMediaPermissionRequestManager(); #endif void requestUserMediaPermissionForFrame(WebCore::UserMediaRequestIdentifier, WebCore::FrameIdentifier, const WebCore::SecurityOriginData& userMediaDocumentOriginIdentifier, const WebCore::SecurityOriginData& topLevelDocumentOriginIdentifier, WebCore::MediaStreamRequest&&); - void enumerateMediaDevicesForFrame(WebCore::FrameIdentifier, const WebCore::SecurityOriginData& userMediaDocumentOriginData, const WebCore::SecurityOriginData& topLevelDocumentOriginData, CompletionHandler&, const String&)>&&); + void enumerateMediaDevicesForFrame(WebCore::FrameIdentifier, const WebCore::SecurityOriginData& userMediaDocumentOriginData, const WebCore::SecurityOriginData& topLevelDocumentOriginData, CompletionHandler&, WebCore::MediaDeviceHashSalts&&)>&&); void beginMonitoringCaptureDevices(); #if ENABLE(ENCRYPTED_MEDIA) diff --git a/Source/WebKit/UIProcess/WebPageProxy.messages.in b/Source/WebKit/UIProcess/WebPageProxy.messages.in index 24a2fb055caa..374e1eb212ef 100644 --- a/Source/WebKit/UIProcess/WebPageProxy.messages.in +++ b/Source/WebKit/UIProcess/WebPageProxy.messages.in @@ -271,7 +271,7 @@ messages -> WebPageProxy { #if ENABLE(MEDIA_STREAM) # MediaSteam messages RequestUserMediaPermissionForFrame(WebCore::UserMediaRequestIdentifier userMediaID, WebCore::FrameIdentifier frameID, struct WebCore::SecurityOriginData userMediaDocumentOriginIdentifier, struct WebCore::SecurityOriginData topLevelDocumentOriginIdentifier, struct WebCore::MediaStreamRequest request) - EnumerateMediaDevicesForFrame(WebCore::FrameIdentifier frameID, struct WebCore::SecurityOriginData userMediaDocumentOriginIdentifier, struct WebCore::SecurityOriginData topLevelDocumentOriginIdentifier) -> (Vector devices, String mediaDeviceIdentifierHashSalt) + EnumerateMediaDevicesForFrame(WebCore::FrameIdentifier frameID, struct WebCore::SecurityOriginData userMediaDocumentOriginIdentifier, struct WebCore::SecurityOriginData topLevelDocumentOriginIdentifier) -> (Vector devices, struct WebCore::MediaDeviceHashSalts mediaDeviceIdentifierHashSalts) BeginMonitoringCaptureDevices() #endif diff --git a/Source/WebKit/UIProcess/WebProcessPool.cpp b/Source/WebKit/UIProcess/WebProcessPool.cpp index 6feb2eb22c39..c1d26c2c07b8 100644 --- a/Source/WebKit/UIProcess/WebProcessPool.cpp +++ b/Source/WebKit/UIProcess/WebProcessPool.cpp @@ -1978,6 +1978,18 @@ void WebProcessPool::removeMockMediaDevice(const String& persistentId) #endif } + +void WebProcessPool::setMockMediaDeviceIsEphemeral(const String& persistentId, bool isEphemeral) +{ +#if ENABLE(MEDIA_STREAM) + MockRealtimeMediaSourceCenter::setDeviceIsEphemeral(persistentId, isEphemeral); + sendToAllProcesses(Messages::WebProcess::SetMockMediaDeviceIsEphemeral { persistentId, isEphemeral }); +#if ENABLE(GPU_PROCESS) + ensureGPUProcess().setMockMediaDeviceIsEphemeral(persistentId, isEphemeral); +#endif +#endif +} + void WebProcessPool::resetMockMediaDevices() { #if ENABLE(MEDIA_STREAM) diff --git a/Source/WebKit/UIProcess/WebProcessPool.h b/Source/WebKit/UIProcess/WebProcessPool.h index 78c4ba6abd5b..8b3e29c5727a 100644 --- a/Source/WebKit/UIProcess/WebProcessPool.h +++ b/Source/WebKit/UIProcess/WebProcessPool.h @@ -466,7 +466,8 @@ class WebProcessPool final void addMockMediaDevice(const WebCore::MockMediaDevice&); void clearMockMediaDevices(); - void removeMockMediaDevice(const String& persistentId); + void removeMockMediaDevice(const String&); + void setMockMediaDeviceIsEphemeral(const String&, bool); void resetMockMediaDevices(); void sendDisplayConfigurationChangedMessageForTesting(); diff --git a/Source/WebKit/UIProcess/glib/UserMediaPermissionRequestManagerProxyGLib.cpp b/Source/WebKit/UIProcess/glib/UserMediaPermissionRequestManagerProxyGLib.cpp index 003b021560cb..c83a4cab265f 100644 --- a/Source/WebKit/UIProcess/glib/UserMediaPermissionRequestManagerProxyGLib.cpp +++ b/Source/WebKit/UIProcess/glib/UserMediaPermissionRequestManagerProxyGLib.cpp @@ -27,13 +27,13 @@ namespace WebKit { using namespace WebCore; -void UserMediaPermissionRequestManagerProxy::platformValidateUserMediaRequestConstraints(RealtimeMediaSourceCenter::ValidConstraintsHandler&& validHandler, RealtimeMediaSourceCenter::InvalidConstraintsHandler&& invalidHandler, String&& deviceIDHashSalt) +void UserMediaPermissionRequestManagerProxy::platformValidateUserMediaRequestConstraints(RealtimeMediaSourceCenter::ValidConstraintsHandler&& validHandler, RealtimeMediaSourceCenter::InvalidConstraintsHandler&& invalidHandler, WebCore::MediaDeviceHashSalts&& deviceIDHashSalts) { - m_page.process().connection()->sendWithAsyncReply(Messages::UserMediaCaptureManager::ValidateUserMediaRequestConstraints(m_currentUserMediaRequest->userRequest(), deviceIDHashSalt), [validHandler = WTFMove(validHandler), invalidHandler = WTFMove(invalidHandler)](std::optional invalidConstraint, Vector audioDevices, Vector videoDevices, std::optional deviceIdentifierHashSalt) mutable { + m_page.process().connection()->sendWithAsyncReply(Messages::UserMediaCaptureManager::ValidateUserMediaRequestConstraints(m_currentUserMediaRequest->userRequest(), WTFMove(deviceIDHashSalts)), [validHandler = WTFMove(validHandler), invalidHandler = WTFMove(invalidHandler)](std::optional invalidConstraint, Vector audioDevices, Vector videoDevices) mutable { if (invalidConstraint) invalidHandler(*invalidConstraint); else - validHandler(WTFMove(audioDevices), WTFMove(videoDevices), WTFMove(*deviceIdentifierHashSalt)); + validHandler(WTFMove(audioDevices), WTFMove(videoDevices)); }); } diff --git a/Source/WebKit/WebProcess/MediaStream/UserMediaPermissionRequestManager.cpp b/Source/WebKit/WebProcess/MediaStream/UserMediaPermissionRequestManager.cpp index 7df63290bc95..2cf131cd9b29 100644 --- a/Source/WebKit/WebProcess/MediaStream/UserMediaPermissionRequestManager.cpp +++ b/Source/WebKit/WebProcess/MediaStream/UserMediaPermissionRequestManager.cpp @@ -118,7 +118,7 @@ void UserMediaPermissionRequestManager::mediaCanStart(Document& document) sendUserMediaRequest(pendingRequest); } -void UserMediaPermissionRequestManager::userMediaAccessWasGranted(UserMediaRequestIdentifier requestID, CaptureDevice&& audioDevice, CaptureDevice&& videoDevice, String&& deviceIdentifierHashSalt, CompletionHandler&& completionHandler) +void UserMediaPermissionRequestManager::userMediaAccessWasGranted(UserMediaRequestIdentifier requestID, CaptureDevice&& audioDevice, CaptureDevice&& videoDevice, WebCore::MediaDeviceHashSalts&& deviceIdentifierHashSalts, CompletionHandler&& completionHandler) { auto request = m_ongoingUserMediaRequests.take(requestID); if (!request) { @@ -126,7 +126,7 @@ void UserMediaPermissionRequestManager::userMediaAccessWasGranted(UserMediaReque return; } - request->allow(WTFMove(audioDevice), WTFMove(videoDevice), WTFMove(deviceIdentifierHashSalt), WTFMove(completionHandler)); + request->allow(WTFMove(audioDevice), WTFMove(videoDevice), WTFMove(deviceIdentifierHashSalts), WTFMove(completionHandler)); } void UserMediaPermissionRequestManager::userMediaAccessWasDenied(UserMediaRequestIdentifier requestID, UserMediaRequest::MediaAccessDenialReason reason, String&& invalidConstraint) @@ -138,11 +138,11 @@ void UserMediaPermissionRequestManager::userMediaAccessWasDenied(UserMediaReques request->deny(reason, WTFMove(invalidConstraint)); } -void UserMediaPermissionRequestManager::enumerateMediaDevices(Document& document, CompletionHandler&, const String&)>&& completionHandler) +void UserMediaPermissionRequestManager::enumerateMediaDevices(Document& document, CompletionHandler&, MediaDeviceHashSalts&&)>&& completionHandler) { auto* frame = document.frame(); if (!frame) { - completionHandler({ }, emptyString()); + completionHandler({ }, { }); return; } diff --git a/Source/WebKit/WebProcess/MediaStream/UserMediaPermissionRequestManager.h b/Source/WebKit/WebProcess/MediaStream/UserMediaPermissionRequestManager.h index 9cb6048bcd2d..312af03bf963 100644 --- a/Source/WebKit/WebProcess/MediaStream/UserMediaPermissionRequestManager.h +++ b/Source/WebKit/WebProcess/MediaStream/UserMediaPermissionRequestManager.h @@ -52,10 +52,10 @@ class UserMediaPermissionRequestManager : public WebCore::MediaCanStartListener void startUserMediaRequest(WebCore::UserMediaRequest&); void cancelUserMediaRequest(WebCore::UserMediaRequest&); - void userMediaAccessWasGranted(WebCore::UserMediaRequestIdentifier, WebCore::CaptureDevice&& audioDevice, WebCore::CaptureDevice&& videoDevice, String&& deviceIdentifierHashSalt, CompletionHandler&&); + void userMediaAccessWasGranted(WebCore::UserMediaRequestIdentifier, WebCore::CaptureDevice&& audioDevice, WebCore::CaptureDevice&& videoDevice, WebCore::MediaDeviceHashSalts&&, CompletionHandler&&); void userMediaAccessWasDenied(WebCore::UserMediaRequestIdentifier, WebCore::UserMediaRequest::MediaAccessDenialReason, String&&); - void enumerateMediaDevices(WebCore::Document&, CompletionHandler&, const String&)>&&); + void enumerateMediaDevices(WebCore::Document&, CompletionHandler&, WebCore::MediaDeviceHashSalts&&)>&&); WebCore::UserMediaClient::DeviceChangeObserverToken addDeviceChangeObserver(WTF::Function&&); void removeDeviceChangeObserver(WebCore::UserMediaClient::DeviceChangeObserverToken); diff --git a/Source/WebKit/WebProcess/WebCoreSupport/WebUserMediaClient.cpp b/Source/WebKit/WebProcess/WebCoreSupport/WebUserMediaClient.cpp index 35ae7d29e585..c7163c4c31cb 100644 --- a/Source/WebKit/WebProcess/WebCoreSupport/WebUserMediaClient.cpp +++ b/Source/WebKit/WebProcess/WebCoreSupport/WebUserMediaClient.cpp @@ -50,7 +50,7 @@ void WebUserMediaClient::cancelUserMediaAccessRequest(UserMediaRequest& request) m_page.userMediaPermissionRequestManager().cancelUserMediaRequest(request); } -void WebUserMediaClient::enumerateMediaDevices(Document& document, CompletionHandler&, const String&)>&& completionHandler) +void WebUserMediaClient::enumerateMediaDevices(Document& document, UserMediaClient::EnumerateDevicesCallback&& completionHandler) { m_page.userMediaPermissionRequestManager().enumerateMediaDevices(document, WTFMove(completionHandler)); } diff --git a/Source/WebKit/WebProcess/WebCoreSupport/WebUserMediaClient.h b/Source/WebKit/WebProcess/WebCoreSupport/WebUserMediaClient.h index 76d41f682789..76b22c3d3ad1 100644 --- a/Source/WebKit/WebProcess/WebCoreSupport/WebUserMediaClient.h +++ b/Source/WebKit/WebProcess/WebCoreSupport/WebUserMediaClient.h @@ -40,7 +40,7 @@ class WebUserMediaClient : public WebCore::UserMediaClient { void requestUserMediaAccess(WebCore::UserMediaRequest&) override; void cancelUserMediaAccessRequest(WebCore::UserMediaRequest&) override; - void enumerateMediaDevices(WebCore::Document&, CompletionHandler&, const String&)>&&) final; + void enumerateMediaDevices(WebCore::Document&, WebCore::UserMediaClient::EnumerateDevicesCallback&&) final; DeviceChangeObserverToken addDeviceChangeObserver(WTF::Function&&) final; void removeDeviceChangeObserver(DeviceChangeObserverToken) final; diff --git a/Source/WebKit/WebProcess/WebPage/WebPage.cpp b/Source/WebKit/WebProcess/WebPage/WebPage.cpp index c54120fd6f5e..c5ff57374f42 100644 --- a/Source/WebKit/WebProcess/WebPage/WebPage.cpp +++ b/Source/WebKit/WebProcess/WebPage/WebPage.cpp @@ -5078,11 +5078,11 @@ void WebPage::didReceiveGeolocationPermissionDecision(GeolocationIdentifier geol #if ENABLE(MEDIA_STREAM) -void WebPage::userMediaAccessWasGranted(UserMediaRequestIdentifier userMediaID, WebCore::CaptureDevice&& audioDevice, WebCore::CaptureDevice&& videoDevice, String&& mediaDeviceIdentifierHashSalt, SandboxExtension::Handle&& handle, CompletionHandler&& completionHandler) +void WebPage::userMediaAccessWasGranted(UserMediaRequestIdentifier userMediaID, WebCore::CaptureDevice&& audioDevice, WebCore::CaptureDevice&& videoDevice, WebCore::MediaDeviceHashSalts&& mediaDeviceIdentifierHashSalts, SandboxExtension::Handle&& handle, CompletionHandler&& completionHandler) { SandboxExtension::consumePermanently(handle); - m_userMediaPermissionRequestManager->userMediaAccessWasGranted(userMediaID, WTFMove(audioDevice), WTFMove(videoDevice), WTFMove(mediaDeviceIdentifierHashSalt), WTFMove(completionHandler)); + m_userMediaPermissionRequestManager->userMediaAccessWasGranted(userMediaID, WTFMove(audioDevice), WTFMove(videoDevice), WTFMove(mediaDeviceIdentifierHashSalts), WTFMove(completionHandler)); } void WebPage::userMediaAccessWasDenied(UserMediaRequestIdentifier userMediaID, uint64_t reason, String&& invalidConstraint) diff --git a/Source/WebKit/WebProcess/WebPage/WebPage.h b/Source/WebKit/WebProcess/WebPage/WebPage.h index cf14fb2a7770..0d108aae519c 100644 --- a/Source/WebKit/WebProcess/WebPage/WebPage.h +++ b/Source/WebKit/WebProcess/WebPage/WebPage.h @@ -1871,7 +1871,7 @@ class WebPage : public API::ObjectImpl, public IP void didReceiveGeolocationPermissionDecision(GeolocationIdentifier, const String& authorizationToken); #if ENABLE(MEDIA_STREAM) - void userMediaAccessWasGranted(WebCore::UserMediaRequestIdentifier, WebCore::CaptureDevice&& audioDeviceUID, WebCore::CaptureDevice&& videoDeviceUID, String&& mediaDeviceIdentifierHashSalt, SandboxExtension::Handle&&, CompletionHandler&&); + void userMediaAccessWasGranted(WebCore::UserMediaRequestIdentifier, WebCore::CaptureDevice&& audioDeviceUID, WebCore::CaptureDevice&& videoDeviceUID, WebCore::MediaDeviceHashSalts&& mediaDeviceIdentifierHashSalt, SandboxExtension::Handle&&, CompletionHandler&&); void userMediaAccessWasDenied(WebCore::UserMediaRequestIdentifier, uint64_t reason, String&& invalidConstraint); #endif diff --git a/Source/WebKit/WebProcess/WebPage/WebPage.messages.in b/Source/WebKit/WebProcess/WebPage/WebPage.messages.in index 9d01ce4d8c0a..98bdc8cfe3ab 100644 --- a/Source/WebKit/WebProcess/WebPage/WebPage.messages.in +++ b/Source/WebKit/WebProcess/WebPage/WebPage.messages.in @@ -410,7 +410,7 @@ GenerateSyntheticEditingCommand(enum:uint8_t WebKit::SyntheticEditingCommandType #if ENABLE(MEDIA_STREAM) # MediaSteam - UserMediaAccessWasGranted(WebCore::UserMediaRequestIdentifier userMediaID, WebCore::CaptureDevice audioDevice, WebCore::CaptureDevice videoDevice, String mediaDeviceIdentifierHashSalt, WebKit::SandboxExtension::Handle sandboxExtensionHandle) -> () + UserMediaAccessWasGranted(WebCore::UserMediaRequestIdentifier userMediaID, WebCore::CaptureDevice audioDevice, WebCore::CaptureDevice videoDevice, struct WebCore::MediaDeviceHashSalts mediaDeviceIdentifierHashSalts, WebKit::SandboxExtension::Handle sandboxExtensionHandle) -> () UserMediaAccessWasDenied(WebCore::UserMediaRequestIdentifier userMediaID, uint64_t reason, String invalidConstraint) CaptureDevicesChanged() #if USE(GSTREAMER) diff --git a/Source/WebKit/WebProcess/WebProcess.cpp b/Source/WebKit/WebProcess/WebProcess.cpp index 7c7c67927f8a..4fb27ab66391 100644 --- a/Source/WebKit/WebProcess/WebProcess.cpp +++ b/Source/WebKit/WebProcess/WebProcess.cpp @@ -1908,6 +1908,11 @@ void WebProcess::removeMockMediaDevice(const String& persistentId) MockRealtimeMediaSourceCenter::removeDevice(persistentId); } +void WebProcess::setMockMediaDeviceIsEphemeral(const String& persistentId, bool isEphemeral) +{ + MockRealtimeMediaSourceCenter::setDeviceIsEphemeral(persistentId, isEphemeral); +} + void WebProcess::resetMockMediaDevices() { MockRealtimeMediaSourceCenter::resetDevices(); diff --git a/Source/WebKit/WebProcess/WebProcess.h b/Source/WebKit/WebProcess/WebProcess.h index c92258eb15f5..73732bd8293e 100644 --- a/Source/WebKit/WebProcess/WebProcess.h +++ b/Source/WebKit/WebProcess/WebProcess.h @@ -503,7 +503,8 @@ class WebProcess : public AuxiliaryProcess #if ENABLE(MEDIA_STREAM) void addMockMediaDevice(const WebCore::MockMediaDevice&); void clearMockMediaDevices(); - void removeMockMediaDevice(const String& persistentId); + void removeMockMediaDevice(const String&); + void setMockMediaDeviceIsEphemeral(const String&, bool); void resetMockMediaDevices(); #if ENABLE(SANDBOX_EXTENSIONS) void grantUserMediaDeviceSandboxExtensions(MediaDeviceSandboxExtensions&&); diff --git a/Source/WebKit/WebProcess/WebProcess.messages.in b/Source/WebKit/WebProcess/WebProcess.messages.in index d5d86c5f3524..46da7aef438b 100644 --- a/Source/WebKit/WebProcess/WebProcess.messages.in +++ b/Source/WebKit/WebProcess/WebProcess.messages.in @@ -138,6 +138,7 @@ messages -> WebProcess LegacyReceiver NotRefCounted { AddMockMediaDevice(struct WebCore::MockMediaDevice device); ClearMockMediaDevices(); RemoveMockMediaDevice(String persistentId); + SetMockMediaDeviceIsEphemeral(String persistentId, bool isEphemeral); ResetMockMediaDevices(); #if ENABLE(SANDBOX_EXTENSIONS) diff --git a/Source/WebKit/WebProcess/cocoa/RemoteRealtimeAudioSource.cpp b/Source/WebKit/WebProcess/cocoa/RemoteRealtimeAudioSource.cpp index 867bd3e53e7a..309a7b26a042 100644 --- a/Source/WebKit/WebProcess/cocoa/RemoteRealtimeAudioSource.cpp +++ b/Source/WebKit/WebProcess/cocoa/RemoteRealtimeAudioSource.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020 Apple Inc. All rights reserved. + * Copyright (C) 2020-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 @@ -35,17 +35,17 @@ namespace WebKit { using namespace WebCore; -Ref RemoteRealtimeAudioSource::create(const CaptureDevice& device, const MediaConstraints* constraints, AtomString&& name, String&& hashSalt, UserMediaCaptureManager& manager, bool shouldCaptureInGPUProcess, PageIdentifier pageIdentifier) +Ref RemoteRealtimeAudioSource::create(const CaptureDevice& device, const MediaConstraints* constraints, MediaDeviceHashSalts&& hashSalts, UserMediaCaptureManager& manager, bool shouldCaptureInGPUProcess, PageIdentifier pageIdentifier) { - auto source = adoptRef(*new RemoteRealtimeAudioSource(RealtimeMediaSourceIdentifier::generate(), device, constraints, WTFMove(name), WTFMove(hashSalt), manager, shouldCaptureInGPUProcess, pageIdentifier)); + auto source = adoptRef(*new RemoteRealtimeAudioSource(RealtimeMediaSourceIdentifier::generate(), device, constraints, WTFMove(hashSalts), manager, shouldCaptureInGPUProcess, pageIdentifier)); manager.addSource(source.copyRef()); manager.remoteCaptureSampleManager().addSource(source.copyRef()); source->createRemoteMediaSource(); return source; } -RemoteRealtimeAudioSource::RemoteRealtimeAudioSource(RealtimeMediaSourceIdentifier identifier, const CaptureDevice& device, const MediaConstraints* constraints, AtomString&& name, String&& hashSalt, UserMediaCaptureManager& manager, bool shouldCaptureInGPUProcess, PageIdentifier pageIdentifier) - : RemoteRealtimeMediaSource(identifier, device, constraints, WTFMove(name), WTFMove(hashSalt), manager, shouldCaptureInGPUProcess, pageIdentifier) +RemoteRealtimeAudioSource::RemoteRealtimeAudioSource(RealtimeMediaSourceIdentifier identifier, const CaptureDevice& device, const MediaConstraints* constraints, MediaDeviceHashSalts&& hashSalts, UserMediaCaptureManager& manager, bool shouldCaptureInGPUProcess, PageIdentifier pageIdentifier) + : RemoteRealtimeMediaSource(identifier, device, constraints, WTFMove(hashSalts), manager, shouldCaptureInGPUProcess, pageIdentifier) { ASSERT(device.type() == CaptureDevice::DeviceType::Microphone); } diff --git a/Source/WebKit/WebProcess/cocoa/RemoteRealtimeAudioSource.h b/Source/WebKit/WebProcess/cocoa/RemoteRealtimeAudioSource.h index 7ad4ca5ba041..17f2f0d03b13 100644 --- a/Source/WebKit/WebProcess/cocoa/RemoteRealtimeAudioSource.h +++ b/Source/WebKit/WebProcess/cocoa/RemoteRealtimeAudioSource.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020 Apple Inc. All rights reserved. + * Copyright (C) 2020-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 @@ -33,13 +33,14 @@ namespace WebKit { class RemoteRealtimeAudioSource final : public RemoteRealtimeMediaSource { public: - static Ref create(const WebCore::CaptureDevice&, const WebCore::MediaConstraints*, AtomString&& name, String&& hashSalt, UserMediaCaptureManager&, bool shouldCaptureInGPUProcess, WebCore::PageIdentifier); + static Ref create(const WebCore::CaptureDevice&, const WebCore::MediaConstraints*, WebCore::MediaDeviceHashSalts&&, UserMediaCaptureManager&, bool shouldCaptureInGPUProcess, WebCore::PageIdentifier); ~RemoteRealtimeAudioSource(); void remoteAudioSamplesAvailable(const MediaTime&, const WebCore::PlatformAudioData&, const WebCore::AudioStreamDescription&, size_t); private: - RemoteRealtimeAudioSource(WebCore::RealtimeMediaSourceIdentifier, const WebCore::CaptureDevice&, const WebCore::MediaConstraints*, AtomString&& name, String&& hashSalt, UserMediaCaptureManager&, bool shouldCaptureInGPUProcess, WebCore::PageIdentifier); + RemoteRealtimeAudioSource(WebCore::RealtimeMediaSourceIdentifier, const WebCore::CaptureDevice&, const WebCore::MediaConstraints*, WebCore::MediaDeviceHashSalts&&, UserMediaCaptureManager&, bool shouldCaptureInGPUProcess, WebCore::PageIdentifier); + }; } // namespace WebKit diff --git a/Source/WebKit/WebProcess/cocoa/RemoteRealtimeMediaSource.cpp b/Source/WebKit/WebProcess/cocoa/RemoteRealtimeMediaSource.cpp index 33dd0678c89d..24a759690eaa 100644 --- a/Source/WebKit/WebProcess/cocoa/RemoteRealtimeMediaSource.cpp +++ b/Source/WebKit/WebProcess/cocoa/RemoteRealtimeMediaSource.cpp @@ -36,32 +36,15 @@ namespace WebKit { using namespace WebCore; -static RealtimeMediaSource::Type toSourceType(CaptureDevice::DeviceType type) -{ - switch (type) { - case CaptureDevice::DeviceType::Microphone: - case CaptureDevice::DeviceType::SystemAudio: - return RealtimeMediaSource::Type::Audio; - case CaptureDevice::DeviceType::Camera: - case CaptureDevice::DeviceType::Screen: - case CaptureDevice::DeviceType::Window: - return RealtimeMediaSource::Type::Video; - case CaptureDevice::DeviceType::Unknown: - case CaptureDevice::DeviceType::Speaker: - ASSERT_NOT_REACHED(); - return RealtimeMediaSource::Type::Audio; - } -} - -RemoteRealtimeMediaSource::RemoteRealtimeMediaSource(RealtimeMediaSourceIdentifier identifier, const CaptureDevice& device, const MediaConstraints* constraints, AtomString&& name, String&& hashSalt, UserMediaCaptureManager& manager, bool shouldCaptureInGPUProcess, PageIdentifier pageIdentifier) - : RealtimeMediaSource(toSourceType(device.type()), WTFMove(name), String { device.persistentId() }, WTFMove(hashSalt), pageIdentifier) +RemoteRealtimeMediaSource::RemoteRealtimeMediaSource(RealtimeMediaSourceIdentifier identifier, const CaptureDevice& device, const MediaConstraints* constraints, MediaDeviceHashSalts&& hashSalts, UserMediaCaptureManager& manager, bool shouldCaptureInGPUProcess, PageIdentifier pageIdentifier) + : RealtimeMediaSource(device, WTFMove(hashSalts), pageIdentifier) , m_proxy(identifier, device, shouldCaptureInGPUProcess, constraints) , m_manager(manager) { } -RemoteRealtimeMediaSource::RemoteRealtimeMediaSource(RemoteRealtimeMediaSourceProxy&& proxy, AtomString&& name, String&& hashSalt, UserMediaCaptureManager& manager, PageIdentifier pageIdentifier) - : RealtimeMediaSource(toSourceType(proxy.device().type()), WTFMove(name), String { proxy.device().persistentId() }, WTFMove(hashSalt), pageIdentifier) +RemoteRealtimeMediaSource::RemoteRealtimeMediaSource(RemoteRealtimeMediaSourceProxy&& proxy, MediaDeviceHashSalts&& hashSalts, UserMediaCaptureManager& manager, PageIdentifier pageIdentifier) + : RealtimeMediaSource(proxy.device(), WTFMove(hashSalts), pageIdentifier) , m_proxy(WTFMove(proxy)) , m_manager(manager) { @@ -69,7 +52,7 @@ RemoteRealtimeMediaSource::RemoteRealtimeMediaSource(RemoteRealtimeMediaSourcePr void RemoteRealtimeMediaSource::createRemoteMediaSource() { - m_proxy.createRemoteMediaSource(deviceIDHashSalt(), pageIdentifier(), [this, protectedThis = Ref { *this }](bool succeeded, auto&& errorMessage, auto&& settings, auto&& capabilities, auto&&, auto, auto) { + m_proxy.createRemoteMediaSource(deviceIDHashSalts(), pageIdentifier(), [this, protectedThis = Ref { *this }](bool succeeded, auto&& errorMessage, auto&& settings, auto&& capabilities, auto&&, auto, auto) { if (!succeeded) { m_proxy.didFail(WTFMove(errorMessage)); return; diff --git a/Source/WebKit/WebProcess/cocoa/RemoteRealtimeMediaSource.h b/Source/WebKit/WebProcess/cocoa/RemoteRealtimeMediaSource.h index 65ed18ad18fe..709753b7a7fa 100644 --- a/Source/WebKit/WebProcess/cocoa/RemoteRealtimeMediaSource.h +++ b/Source/WebKit/WebProcess/cocoa/RemoteRealtimeMediaSource.h @@ -41,8 +41,8 @@ class RemoteRealtimeMediaSource : public WebCore::RealtimeMediaSource #endif { public: - RemoteRealtimeMediaSource(WebCore::RealtimeMediaSourceIdentifier, const WebCore::CaptureDevice&, const WebCore::MediaConstraints*, AtomString&& name, String&& hashSalt, UserMediaCaptureManager&, bool shouldCaptureInGPUProcess, WebCore::PageIdentifier); - RemoteRealtimeMediaSource(RemoteRealtimeMediaSourceProxy&&, AtomString&& name, String&& hashSalt, UserMediaCaptureManager&, WebCore::PageIdentifier); + RemoteRealtimeMediaSource(WebCore::RealtimeMediaSourceIdentifier, const WebCore::CaptureDevice&, const WebCore::MediaConstraints*, WebCore::MediaDeviceHashSalts&&, UserMediaCaptureManager&, bool shouldCaptureInGPUProcess, WebCore::PageIdentifier); + RemoteRealtimeMediaSource(RemoteRealtimeMediaSourceProxy&&, WebCore::MediaDeviceHashSalts&&, UserMediaCaptureManager&, WebCore::PageIdentifier); WebCore::RealtimeMediaSourceIdentifier identifier() const { return m_proxy.identifier(); } IPC::Connection& connection() { return m_proxy.connection(); } diff --git a/Source/WebKit/WebProcess/cocoa/RemoteRealtimeMediaSourceProxy.cpp b/Source/WebKit/WebProcess/cocoa/RemoteRealtimeMediaSourceProxy.cpp index 4917190fa213..37b5eda964f0 100644 --- a/Source/WebKit/WebProcess/cocoa/RemoteRealtimeMediaSourceProxy.cpp +++ b/Source/WebKit/WebProcess/cocoa/RemoteRealtimeMediaSourceProxy.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020 Apple Inc. All rights reserved. + * Copyright (C) 2020-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 @@ -90,9 +90,9 @@ void RemoteRealtimeMediaSourceProxy::endProducingData() m_connection->send(Messages::UserMediaCaptureManagerProxy::EndProducingData { m_identifier }, 0); } -void RemoteRealtimeMediaSourceProxy::createRemoteMediaSource(const String& deviceIDHashSalt, WebCore::PageIdentifier pageIdentifier, CreateCallback&& callback, bool shouldUseRemoteFrame) +void RemoteRealtimeMediaSourceProxy::createRemoteMediaSource(const MediaDeviceHashSalts& deviceIDHashSalts, WebCore::PageIdentifier pageIdentifier, CreateCallback&& callback, bool shouldUseRemoteFrame) { - m_connection->sendWithAsyncReply(Messages::UserMediaCaptureManagerProxy::CreateMediaSourceForCaptureDeviceWithConstraints(identifier(), m_device, deviceIDHashSalt, m_constraints, shouldUseRemoteFrame, pageIdentifier), WTFMove(callback)); + m_connection->sendWithAsyncReply(Messages::UserMediaCaptureManagerProxy::CreateMediaSourceForCaptureDeviceWithConstraints(identifier(), m_device, deviceIDHashSalts, m_constraints, shouldUseRemoteFrame, pageIdentifier), WTFMove(callback)); } RemoteRealtimeMediaSourceProxy RemoteRealtimeMediaSourceProxy::clone() diff --git a/Source/WebKit/WebProcess/cocoa/RemoteRealtimeMediaSourceProxy.h b/Source/WebKit/WebProcess/cocoa/RemoteRealtimeMediaSourceProxy.h index 1e1be14e93f0..d59ecb53759d 100644 --- a/Source/WebKit/WebProcess/cocoa/RemoteRealtimeMediaSourceProxy.h +++ b/Source/WebKit/WebProcess/cocoa/RemoteRealtimeMediaSourceProxy.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020 Apple Inc. All rights reserved. + * Copyright (C) 2020-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 @@ -57,7 +57,7 @@ class RemoteRealtimeMediaSourceProxy { bool shouldCaptureInGPUProcess() const { return m_shouldCaptureInGPUProcess; } using CreateCallback = CompletionHandler&&, WebCore::IntSize, double)>; - void createRemoteMediaSource(const String&, WebCore::PageIdentifier, CreateCallback&&, bool shouldUseRemoteFrame = false); + void createRemoteMediaSource(const WebCore::MediaDeviceHashSalts&, WebCore::PageIdentifier, CreateCallback&&, bool shouldUseRemoteFrame = false); RemoteRealtimeMediaSourceProxy clone(); void createRemoteCloneSource(WebCore::RealtimeMediaSourceIdentifier, WebCore::PageIdentifier); diff --git a/Source/WebKit/WebProcess/cocoa/RemoteRealtimeVideoSource.cpp b/Source/WebKit/WebProcess/cocoa/RemoteRealtimeVideoSource.cpp index 372f6cc0f245..8f49154811f7 100644 --- a/Source/WebKit/WebProcess/cocoa/RemoteRealtimeVideoSource.cpp +++ b/Source/WebKit/WebProcess/cocoa/RemoteRealtimeVideoSource.cpp @@ -33,23 +33,23 @@ namespace WebKit { using namespace WebCore; -Ref RemoteRealtimeVideoSource::create(const CaptureDevice& device, const MediaConstraints* constraints, String&& hashSalt, UserMediaCaptureManager& manager, bool shouldCaptureInGPUProcess, PageIdentifier pageIdentifier) +Ref RemoteRealtimeVideoSource::create(const CaptureDevice& device, const MediaConstraints* constraints, MediaDeviceHashSalts&& hashSalts, UserMediaCaptureManager& manager, bool shouldCaptureInGPUProcess, PageIdentifier pageIdentifier) { - auto source = adoptRef(*new RemoteRealtimeVideoSource(RealtimeMediaSourceIdentifier::generate(), device, constraints, WTFMove(hashSalt), manager, shouldCaptureInGPUProcess, pageIdentifier)); + auto source = adoptRef(*new RemoteRealtimeVideoSource(RealtimeMediaSourceIdentifier::generate(), device, constraints, WTFMove(hashSalts), manager, shouldCaptureInGPUProcess, pageIdentifier)); manager.addSource(source.copyRef()); manager.remoteCaptureSampleManager().addSource(source.copyRef()); source->createRemoteMediaSource(); return source; } -RemoteRealtimeVideoSource::RemoteRealtimeVideoSource(RealtimeMediaSourceIdentifier identifier, const CaptureDevice& device, const MediaConstraints* constraints, String&& hashSalt, UserMediaCaptureManager& manager, bool shouldCaptureInGPUProcess, PageIdentifier pageIdentifier) - : RemoteRealtimeMediaSource(identifier, device, constraints, AtomString { device.label() }, WTFMove(hashSalt), manager, shouldCaptureInGPUProcess, pageIdentifier) +RemoteRealtimeVideoSource::RemoteRealtimeVideoSource(RealtimeMediaSourceIdentifier identifier, const CaptureDevice& device, const MediaConstraints* constraints, MediaDeviceHashSalts&& hashSalts, UserMediaCaptureManager& manager, bool shouldCaptureInGPUProcess, PageIdentifier pageIdentifier) + : RemoteRealtimeMediaSource(identifier, device, constraints, WTFMove(hashSalts), manager, shouldCaptureInGPUProcess, pageIdentifier) { ASSERT(this->pageIdentifier()); } -RemoteRealtimeVideoSource::RemoteRealtimeVideoSource(RemoteRealtimeMediaSourceProxy&& proxy, AtomString&& name, String&& hashSalt, UserMediaCaptureManager& manager, PageIdentifier pageIdentifier) - : RemoteRealtimeMediaSource(WTFMove(proxy), WTFMove(name), WTFMove(hashSalt), manager, pageIdentifier) +RemoteRealtimeVideoSource::RemoteRealtimeVideoSource(RemoteRealtimeMediaSourceProxy&& proxy, MediaDeviceHashSalts&& hashSalts, UserMediaCaptureManager& manager, PageIdentifier pageIdentifier) + : RemoteRealtimeMediaSource(WTFMove(proxy), WTFMove(hashSalts), manager, pageIdentifier) { ASSERT(this->pageIdentifier()); } @@ -75,7 +75,7 @@ Ref RemoteRealtimeVideoSource::clone() if (isEnded() || proxy().isEnded()) return *this; - auto source = adoptRef(*new RemoteRealtimeVideoSource(proxy().clone(), AtomString { name() }, deviceIDHashSalt(), manager(), pageIdentifier())); + auto source = adoptRef(*new RemoteRealtimeVideoSource(proxy().clone(), MediaDeviceHashSalts { deviceIDHashSalts() }, manager(), pageIdentifier())); source->setSettings(RealtimeMediaSourceSettings { settings() }); source->setCapabilities(RealtimeMediaSourceCapabilities { capabilities() }); diff --git a/Source/WebKit/WebProcess/cocoa/RemoteRealtimeVideoSource.h b/Source/WebKit/WebProcess/cocoa/RemoteRealtimeVideoSource.h index 303d226bb46b..f5549440a369 100644 --- a/Source/WebKit/WebProcess/cocoa/RemoteRealtimeVideoSource.h +++ b/Source/WebKit/WebProcess/cocoa/RemoteRealtimeVideoSource.h @@ -43,14 +43,14 @@ class UserMediaCaptureManager; class RemoteRealtimeVideoSource final : public RemoteRealtimeMediaSource { public: - static Ref create(const WebCore::CaptureDevice&, const WebCore::MediaConstraints*, String&& hashSalt, UserMediaCaptureManager&, bool shouldCaptureInGPUProcess, WebCore::PageIdentifier); + static Ref create(const WebCore::CaptureDevice&, const WebCore::MediaConstraints*, WebCore::MediaDeviceHashSalts&&, UserMediaCaptureManager&, bool shouldCaptureInGPUProcess, WebCore::PageIdentifier); ~RemoteRealtimeVideoSource(); void remoteVideoFrameAvailable(WebCore::VideoFrame&, WebCore::VideoFrameTimeMetadata); private: - RemoteRealtimeVideoSource(WebCore::RealtimeMediaSourceIdentifier, const WebCore::CaptureDevice&, const WebCore::MediaConstraints*, String&& hashSalt, UserMediaCaptureManager&, bool shouldCaptureInGPUProcess, WebCore::PageIdentifier); - RemoteRealtimeVideoSource(RemoteRealtimeMediaSourceProxy&&, AtomString&& name, String&& hashSalt, UserMediaCaptureManager&, WebCore::PageIdentifier); + RemoteRealtimeVideoSource(WebCore::RealtimeMediaSourceIdentifier, const WebCore::CaptureDevice&, const WebCore::MediaConstraints*, WebCore::MediaDeviceHashSalts&&, UserMediaCaptureManager&, bool shouldCaptureInGPUProcess, WebCore::PageIdentifier); + RemoteRealtimeVideoSource(RemoteRealtimeMediaSourceProxy&&, WebCore::MediaDeviceHashSalts&&, UserMediaCaptureManager&, WebCore::PageIdentifier); Ref clone() final; void endProducingData() final; diff --git a/Source/WebKit/WebProcess/cocoa/UserMediaCaptureManager.cpp b/Source/WebKit/WebProcess/cocoa/UserMediaCaptureManager.cpp index 3a31a74a3fc4..94e0d0ab7ca4 100644 --- a/Source/WebKit/WebProcess/cocoa/UserMediaCaptureManager.cpp +++ b/Source/WebKit/WebProcess/cocoa/UserMediaCaptureManager.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017-2018 Apple Inc. All rights reserved. + * Copyright (C) 2017-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 @@ -194,7 +194,7 @@ void UserMediaCaptureManager::applyConstraintsFailed(RealtimeMediaSourceIdentifi }, [](std::nullptr_t) { }); } -CaptureSourceOrError UserMediaCaptureManager::AudioFactory::createAudioCaptureSource(const CaptureDevice& device, String&& hashSalt, const MediaConstraints* constraints, PageIdentifier pageIdentifier) +CaptureSourceOrError UserMediaCaptureManager::AudioFactory::createAudioCaptureSource(const CaptureDevice& device, MediaDeviceHashSalts&& hashSalts, const MediaConstraints* constraints, PageIdentifier pageIdentifier) { #if !ENABLE(GPU_PROCESS) if (m_shouldCaptureInGPUProcess) @@ -207,7 +207,7 @@ CaptureSourceOrError UserMediaCaptureManager::AudioFactory::createAudioCaptureSo DeprecatedGlobalSettings::setShouldManageAudioSessionCategory(true); #endif - return RemoteRealtimeAudioSource::create(device, constraints, { }, WTFMove(hashSalt), m_manager, m_shouldCaptureInGPUProcess, pageIdentifier); + return RemoteRealtimeAudioSource::create(device, constraints, WTFMove(hashSalts), m_manager, m_shouldCaptureInGPUProcess, pageIdentifier); } void UserMediaCaptureManager::AudioFactory::setShouldCaptureInGPUProcess(bool value) @@ -220,7 +220,7 @@ void UserMediaCaptureManager::VideoFactory::setShouldCaptureInGPUProcess(bool va m_shouldCaptureInGPUProcess = value; } -CaptureSourceOrError UserMediaCaptureManager::VideoFactory::createVideoCaptureSource(const CaptureDevice& device, String&& hashSalt, const MediaConstraints* constraints, PageIdentifier pageIdentifier) +CaptureSourceOrError UserMediaCaptureManager::VideoFactory::createVideoCaptureSource(const CaptureDevice& device, MediaDeviceHashSalts&& hashSalts, const MediaConstraints* constraints, PageIdentifier pageIdentifier) { #if !ENABLE(GPU_PROCESS) if (m_shouldCaptureInGPUProcess) @@ -229,10 +229,10 @@ CaptureSourceOrError UserMediaCaptureManager::VideoFactory::createVideoCaptureSo if (m_shouldCaptureInGPUProcess) m_manager.m_remoteCaptureSampleManager.setVideoFrameObjectHeapProxy(&WebProcess::singleton().ensureGPUProcessConnection().videoFrameObjectHeapProxy()); - return RemoteRealtimeVideoSource::create(device, constraints, WTFMove(hashSalt), m_manager, m_shouldCaptureInGPUProcess, pageIdentifier); + return RemoteRealtimeVideoSource::create(device, constraints, WTFMove(hashSalts), m_manager, m_shouldCaptureInGPUProcess, pageIdentifier); } -CaptureSourceOrError UserMediaCaptureManager::DisplayFactory::createDisplayCaptureSource(const CaptureDevice& device, String&& hashSalt, const MediaConstraints* constraints, PageIdentifier pageIdentifier) +CaptureSourceOrError UserMediaCaptureManager::DisplayFactory::createDisplayCaptureSource(const CaptureDevice& device, MediaDeviceHashSalts&& hashSalts, const MediaConstraints* constraints, PageIdentifier pageIdentifier) { #if !ENABLE(GPU_PROCESS) if (m_shouldCaptureInGPUProcess) @@ -241,7 +241,7 @@ CaptureSourceOrError UserMediaCaptureManager::DisplayFactory::createDisplayCaptu if (m_shouldCaptureInGPUProcess) m_manager.m_remoteCaptureSampleManager.setVideoFrameObjectHeapProxy(&WebProcess::singleton().ensureGPUProcessConnection().videoFrameObjectHeapProxy()); - return RemoteRealtimeVideoSource::create(device, constraints, WTFMove(hashSalt), m_manager, m_shouldCaptureInGPUProcess, pageIdentifier); + return RemoteRealtimeVideoSource::create(device, constraints, WTFMove(hashSalts), m_manager, m_shouldCaptureInGPUProcess, pageIdentifier); } void UserMediaCaptureManager::DisplayFactory::setShouldCaptureInGPUProcess(bool value) diff --git a/Source/WebKit/WebProcess/cocoa/UserMediaCaptureManager.h b/Source/WebKit/WebProcess/cocoa/UserMediaCaptureManager.h index 53e1eb4a3e87..f3211d5df17e 100644 --- a/Source/WebKit/WebProcess/cocoa/UserMediaCaptureManager.h +++ b/Source/WebKit/WebProcess/cocoa/UserMediaCaptureManager.h @@ -72,7 +72,7 @@ class UserMediaCaptureManager : public WebProcessSupplement, public IPC::Message void setShouldCaptureInGPUProcess(bool); private: - WebCore::CaptureSourceOrError createAudioCaptureSource(const WebCore::CaptureDevice&, String&& hashSalt, const WebCore::MediaConstraints*, WebCore::PageIdentifier) final; + WebCore::CaptureSourceOrError createAudioCaptureSource(const WebCore::CaptureDevice&, WebCore::MediaDeviceHashSalts&&, const WebCore::MediaConstraints*, WebCore::PageIdentifier) final; WebCore::CaptureDeviceManager& audioCaptureDeviceManager() final { return m_manager.m_noOpCaptureDeviceManager; } const Vector& speakerDevices() const final { return m_speakerDevices; } @@ -86,7 +86,7 @@ class UserMediaCaptureManager : public WebProcessSupplement, public IPC::Message void setShouldCaptureInGPUProcess(bool); private: - WebCore::CaptureSourceOrError createVideoCaptureSource(const WebCore::CaptureDevice&, String&& hashSalt, const WebCore::MediaConstraints*, WebCore::PageIdentifier) final; + WebCore::CaptureSourceOrError createVideoCaptureSource(const WebCore::CaptureDevice&, WebCore::MediaDeviceHashSalts&&, const WebCore::MediaConstraints*, WebCore::PageIdentifier) final; WebCore::CaptureDeviceManager& videoCaptureDeviceManager() final { return m_manager.m_noOpCaptureDeviceManager; } UserMediaCaptureManager& m_manager; @@ -98,7 +98,7 @@ class UserMediaCaptureManager : public WebProcessSupplement, public IPC::Message void setShouldCaptureInGPUProcess(bool); private: - WebCore::CaptureSourceOrError createDisplayCaptureSource(const WebCore::CaptureDevice&, String&&, const WebCore::MediaConstraints*, WebCore::PageIdentifier) final; + WebCore::CaptureSourceOrError createDisplayCaptureSource(const WebCore::CaptureDevice&, WebCore::MediaDeviceHashSalts&&, const WebCore::MediaConstraints*, WebCore::PageIdentifier) final; WebCore::DisplayCaptureManager& displayCaptureDeviceManager() final { return m_manager.m_noOpCaptureDeviceManager; } UserMediaCaptureManager& m_manager; diff --git a/Source/WebKit/WebProcess/glib/UserMediaCaptureManager.cpp b/Source/WebKit/WebProcess/glib/UserMediaCaptureManager.cpp index 5b81332533f6..4cdc7facce24 100644 --- a/Source/WebKit/WebProcess/glib/UserMediaCaptureManager.cpp +++ b/Source/WebKit/WebProcess/glib/UserMediaCaptureManager.cpp @@ -31,6 +31,7 @@ #include "UserMediaCaptureManagerMessages.h" #include "WebProcess.h" #include +#include #include #include @@ -48,20 +49,20 @@ UserMediaCaptureManager::~UserMediaCaptureManager() m_process.removeMessageReceiver(Messages::UserMediaCaptureManager::messageReceiverName()); } -void UserMediaCaptureManager::validateUserMediaRequestConstraints(WebCore::MediaStreamRequest request, String hashSalt, ValidateUserMediaRequestConstraintsCallback&& completionHandler) +void UserMediaCaptureManager::validateUserMediaRequestConstraints(WebCore::MediaStreamRequest request, WebCore::MediaDeviceHashSalts&& deviceIdentifierHashSalts, ValidateUserMediaRequestConstraintsCallback&& completionHandler) { m_validateUserMediaRequestConstraintsCallback = WTFMove(completionHandler); auto invalidHandler = [this](const String& invalidConstraint) mutable { Vector audioDevices; Vector videoDevices; - m_validateUserMediaRequestConstraintsCallback(invalidConstraint, audioDevices, videoDevices, { }); + m_validateUserMediaRequestConstraintsCallback(invalidConstraint, audioDevices, videoDevices); }; - auto validHandler = [this](Vector&& audioDevices, Vector&& videoDevices, String&& deviceIdentifierHashSalt) mutable { - m_validateUserMediaRequestConstraintsCallback(std::nullopt, audioDevices, videoDevices, deviceIdentifierHashSalt); + auto validHandler = [this](Vector&& audioDevices, Vector&& videoDevices) mutable { + m_validateUserMediaRequestConstraintsCallback(std::nullopt, audioDevices, videoDevices); }; - RealtimeMediaSourceCenter::singleton().validateRequestConstraints(WTFMove(validHandler), WTFMove(invalidHandler), request, WTFMove(hashSalt)); + RealtimeMediaSourceCenter::singleton().validateRequestConstraints(WTFMove(validHandler), WTFMove(invalidHandler), request, WTFMove(deviceIdentifierHashSalts)); } void UserMediaCaptureManager::getMediaStreamDevices(GetMediaStreamDevicesCallback&& completionHandler) diff --git a/Source/WebKit/WebProcess/glib/UserMediaCaptureManager.h b/Source/WebKit/WebProcess/glib/UserMediaCaptureManager.h index 28e21c5dfd36..83febde79d9c 100644 --- a/Source/WebKit/WebProcess/glib/UserMediaCaptureManager.h +++ b/Source/WebKit/WebProcess/glib/UserMediaCaptureManager.h @@ -33,6 +33,7 @@ namespace WebCore { class CaptureDevice; +struct MediaDeviceHashSalts; struct MediaStreamRequest; } @@ -54,8 +55,8 @@ class UserMediaCaptureManager : public WebProcessSupplement, public IPC::Message void didReceiveMessage(IPC::Connection&, IPC::Decoder&) final; // Messages::UserMediaCaptureManager - using ValidateUserMediaRequestConstraintsCallback = CompletionHandler invalidConstraint, Vector& audioDevices, Vector& videoDevices, std::optional deviceIdentifierHashSalt)>; - void validateUserMediaRequestConstraints(WebCore::MediaStreamRequest, String hashSalt, ValidateUserMediaRequestConstraintsCallback&&); + using ValidateUserMediaRequestConstraintsCallback = CompletionHandler invalidConstraint, Vector& audioDevices, Vector& videoDevices)>; + void validateUserMediaRequestConstraints(WebCore::MediaStreamRequest, WebCore::MediaDeviceHashSalts&&, ValidateUserMediaRequestConstraintsCallback&&); ValidateUserMediaRequestConstraintsCallback m_validateUserMediaRequestConstraintsCallback; using GetMediaStreamDevicesCallback = CompletionHandler&&)>; diff --git a/Source/WebKit/WebProcess/glib/UserMediaCaptureManager.messages.in b/Source/WebKit/WebProcess/glib/UserMediaCaptureManager.messages.in index a5482917886e..d26114db48b6 100644 --- a/Source/WebKit/WebProcess/glib/UserMediaCaptureManager.messages.in +++ b/Source/WebKit/WebProcess/glib/UserMediaCaptureManager.messages.in @@ -24,7 +24,7 @@ #if ENABLE(MEDIA_STREAM) messages -> UserMediaCaptureManager NotRefCounted { - ValidateUserMediaRequestConstraints(struct WebCore::MediaStreamRequest request, String hashSalt) -> (std::optional invalidConstraint, Vector audioDevices, Vector videoDevices, std::optional deviceIdentifierHashSalt) + ValidateUserMediaRequestConstraints(struct WebCore::MediaStreamRequest request, struct WebCore::MediaDeviceHashSalts mediaDeviceIdentifierHashSalts) -> (std::optional invalidConstraint, Vector audioDevices, Vector videoDevices) GetMediaStreamDevices() -> (Vector devices) } diff --git a/Tools/WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl b/Tools/WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl index 6c4a93783b97..a0869b2ae9d1 100644 --- a/Tools/WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl +++ b/Tools/WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl @@ -384,6 +384,7 @@ interface TestRunner { undefined addMockScreenDevice(DOMString persistentId, DOMString label); undefined clearMockMediaDevices(); undefined removeMockMediaDevice(DOMString persistentId); + undefined setMockMediaDeviceIsEphemeral(DOMString persistentId, boolean isEphemeral); undefined resetMockMediaDevices(); undefined setMockCameraOrientation(unsigned long orientation); boolean isMockRealtimeMediaSourceCenterEnabled(); diff --git a/Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp b/Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp index 48122e228f91..30e7673d7ea9 100644 --- a/Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp +++ b/Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp @@ -1814,6 +1814,14 @@ void TestRunner::removeMockMediaDevice(JSStringRef persistentId) postSynchronousMessage("RemoveMockMediaDevice", toWK(persistentId)); } +void TestRunner::setMockMediaDeviceIsEphemeral(JSStringRef persistentId, bool isEphemeral) +{ + postSynchronousMessage("SetMockMediaDeviceIsEphemeral", createWKDictionary({ + { "PersistentID", toWK(persistentId) }, + { "IsEphemeral", adoptWK(WKBooleanCreate(isEphemeral)) }, + })); +} + void TestRunner::resetMockMediaDevices() { postSynchronousMessage("ResetMockMediaDevices"); diff --git a/Tools/WebKitTestRunner/InjectedBundle/TestRunner.h b/Tools/WebKitTestRunner/InjectedBundle/TestRunner.h index dd74ad934a2c..bebb57bd3453 100644 --- a/Tools/WebKitTestRunner/InjectedBundle/TestRunner.h +++ b/Tools/WebKitTestRunner/InjectedBundle/TestRunner.h @@ -495,6 +495,7 @@ class TestRunner : public JSWrappable { void addMockScreenDevice(JSStringRef persistentId, JSStringRef label); void clearMockMediaDevices(); void removeMockMediaDevice(JSStringRef persistentId); + void setMockMediaDeviceIsEphemeral(JSStringRef persistentId, bool isEphemeral); void resetMockMediaDevices(); void setMockCameraOrientation(unsigned); bool isMockRealtimeMediaSourceCenterEnabled(); diff --git a/Tools/WebKitTestRunner/TestController.cpp b/Tools/WebKitTestRunner/TestController.cpp index 2f62a74e3adb..f684da3632a6 100644 --- a/Tools/WebKitTestRunner/TestController.cpp +++ b/Tools/WebKitTestRunner/TestController.cpp @@ -3673,6 +3673,11 @@ void TestController::removeMockMediaDevice(WKStringRef persistentID) WKRemoveMockMediaDevice(platformContext(), persistentID); } +void TestController::setMockMediaDeviceIsEphemeral(WKStringRef persistentID, bool isEphemeral) +{ + WKSetMockMediaDeviceIsEphemeral(platformContext(), persistentID, isEphemeral); +} + void TestController::resetMockMediaDevices() { WKResetMockMediaDevices(platformContext()); diff --git a/Tools/WebKitTestRunner/TestController.h b/Tools/WebKitTestRunner/TestController.h index cbf39d251c78..9c7f3c198fd3 100644 --- a/Tools/WebKitTestRunner/TestController.h +++ b/Tools/WebKitTestRunner/TestController.h @@ -316,6 +316,7 @@ class TestController { void addMockMediaDevice(WKStringRef persistentID, WKStringRef label, WKStringRef type); void clearMockMediaDevices(); void removeMockMediaDevice(WKStringRef persistentID); + void setMockMediaDeviceIsEphemeral(WKStringRef, bool); void resetMockMediaDevices(); void setMockCameraOrientation(uint64_t); bool isMockRealtimeMediaSourceCenterEnabled() const; diff --git a/Tools/WebKitTestRunner/TestInvocation.cpp b/Tools/WebKitTestRunner/TestInvocation.cpp index c4a4f1c4cb6a..73af5c1cb837 100644 --- a/Tools/WebKitTestRunner/TestInvocation.cpp +++ b/Tools/WebKitTestRunner/TestInvocation.cpp @@ -961,6 +961,14 @@ WKRetainPtr TestInvocation::didReceiveSynchronousMessageFromInjectedB return nullptr; } + if (WKStringIsEqualToUTF8CString(messageName, "SetMockMediaDeviceIsEphemeral")) { + auto messageBodyDictionary = dictionaryValue(messageBody); + auto persistentID = stringValue(messageBodyDictionary, "PersistentID"); + bool isEphemeral = booleanValue(messageBodyDictionary, "IsEphemeral"); + TestController::singleton().setMockMediaDeviceIsEphemeral(persistentID, isEphemeral); + return nullptr; + } + if (WKStringIsEqualToUTF8CString(messageName, "SetMockCameraOrientation")) { TestController::singleton().setMockCameraOrientation(uint64Value(messageBody)); return nullptr;