diff options
author | Jüri Valdmann <juri.valdmann@qt.io> | 2019-10-10 13:53:17 +0200 |
---|---|---|
committer | Jüri Valdmann <juri.valdmann@qt.io> | 2019-10-17 10:46:29 +0200 |
commit | 0d8e9d612951f2501f7e1f92f0173ab0e680324e (patch) | |
tree | a0d2a54e6c17f42ca4ecc7aa30c744435e59c0b3 /src/core/media_capture_devices_dispatcher.cpp | |
parent | 0cbd705b119169db0dc6cb83f811a045570dd975 (diff) |
Fix getDisplayMedia crash
The MEDIA_DISPLAY_VIDEO_CAPTURE stream type is handled incorrectly by
MediaCaptureDevicesDispatcher causing a crash when an unexpected type of media
device is returned to Chromium.
This patch only fixes the crash, screen sharing is nonetheless not properly
supported by WebEngine due to limitations of the public API which does not allow
selecting between screens, not to mention windows or tabs.
On Linux WebRTC's ScreenCapturer is not even built since it depends on use_x11
being set in GN.
Fixes: QTBUG-78016
Change-Id: I7fa49febaba1be94bdb6c31265dfc24ee809d635
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Diffstat (limited to 'src/core/media_capture_devices_dispatcher.cpp')
-rw-r--r-- | src/core/media_capture_devices_dispatcher.cpp | 76 |
1 files changed, 41 insertions, 35 deletions
diff --git a/src/core/media_capture_devices_dispatcher.cpp b/src/core/media_capture_devices_dispatcher.cpp index ecc46f244..29230c27b 100644 --- a/src/core/media_capture_devices_dispatcher.cpp +++ b/src/core/media_capture_devices_dispatcher.cpp @@ -87,22 +87,25 @@ const blink::MediaStreamDevice *findDeviceWithId(const blink::MediaStreamDevices return 0; } -// Based on chrome/browser/media/desktop_capture_access_handler.cc: -void getDevicesForDesktopCapture(blink::MediaStreamDevices *devices, content::DesktopMediaID mediaId, bool captureAudio) +// Based on chrome/browser/media/webrtc/desktop_capture_devices_util.cc: +void getDevicesForDesktopCapture(blink::MediaStreamDevices *devices, + content::DesktopMediaID mediaId, + bool captureAudio, + blink::MediaStreamType videoType, + blink::MediaStreamType audioType) { DCHECK_CURRENTLY_ON(BrowserThread::UI); // Add selected desktop source to the list. - devices->push_back(blink::MediaStreamDevice(blink::MEDIA_GUM_DESKTOP_VIDEO_CAPTURE, mediaId.ToString(), "Screen")); + devices->push_back(blink::MediaStreamDevice(videoType, mediaId.ToString(), mediaId.ToString())); if (captureAudio) { if (mediaId.type == content::DesktopMediaID::TYPE_WEB_CONTENTS) { devices->push_back( - blink::MediaStreamDevice(blink::MEDIA_GUM_DESKTOP_AUDIO_CAPTURE, - mediaId.ToString(), "Tab audio")); + blink::MediaStreamDevice(audioType, mediaId.ToString(), "Tab audio")); } else { // Use the special loopback device ID for system audio capture. devices->push_back(blink::MediaStreamDevice( - blink::MEDIA_GUM_DESKTOP_AUDIO_CAPTURE, + audioType, media::AudioDeviceDescription::kLoopbackInputDeviceId, "System Audio")); } @@ -151,19 +154,27 @@ content::DesktopMediaID getDefaultScreenId() WebContentsAdapterClient::MediaRequestFlags mediaRequestFlagsForRequest(const content::MediaStreamRequest &request) { - WebContentsAdapterClient::MediaRequestFlags requestFlags = WebContentsAdapterClient::MediaNone; + if (request.audio_type == blink::MEDIA_DEVICE_AUDIO_CAPTURE && + request.video_type == blink::MEDIA_DEVICE_VIDEO_CAPTURE) + return {WebContentsAdapterClient::MediaAudioCapture, WebContentsAdapterClient::MediaVideoCapture}; - if (request.audio_type == blink::MEDIA_DEVICE_AUDIO_CAPTURE) - requestFlags |= WebContentsAdapterClient::MediaAudioCapture; - else if (request.audio_type == blink::MEDIA_GUM_DESKTOP_AUDIO_CAPTURE) - requestFlags |= WebContentsAdapterClient::MediaDesktopAudioCapture; + if (request.audio_type == blink::MEDIA_DEVICE_AUDIO_CAPTURE && + request.video_type == blink::MEDIA_NO_SERVICE) + return {WebContentsAdapterClient::MediaAudioCapture}; - if (request.video_type == blink::MEDIA_DEVICE_VIDEO_CAPTURE) - requestFlags |= WebContentsAdapterClient::MediaVideoCapture; - else if (request.video_type == blink::MEDIA_GUM_DESKTOP_VIDEO_CAPTURE) - requestFlags |= WebContentsAdapterClient::MediaDesktopVideoCapture; + if (request.audio_type == blink::MEDIA_NO_SERVICE && + request.video_type == blink::MEDIA_DEVICE_VIDEO_CAPTURE) + return {WebContentsAdapterClient::MediaVideoCapture}; - return requestFlags; + if (request.audio_type == blink::MEDIA_GUM_DESKTOP_AUDIO_CAPTURE && + request.video_type == blink::MEDIA_GUM_DESKTOP_VIDEO_CAPTURE) + return {WebContentsAdapterClient::MediaDesktopAudioCapture, WebContentsAdapterClient::MediaDesktopVideoCapture}; + + if (request.video_type == blink::MEDIA_GUM_DESKTOP_VIDEO_CAPTURE || + request.video_type == blink::MEDIA_DISPLAY_VIDEO_CAPTURE) + return {WebContentsAdapterClient::MediaDesktopVideoCapture}; + + return {}; } } // namespace @@ -198,14 +209,13 @@ void MediaCaptureDevicesDispatcher::handleMediaAccessPermissionResponse(content: if (!securityOriginsMatch) qWarning("Security origin mismatch for media access permission: %s requested and %s provided\n", qPrintable(requestSecurityOrigin.toString()), qPrintable(securityOrigin.toString())); - bool microphoneRequested = - (request.audio_type && authorizationFlags & WebContentsAdapterClient::MediaAudioCapture); - bool webcamRequested = - (request.video_type && authorizationFlags & WebContentsAdapterClient::MediaVideoCapture); - bool desktopAudioRequested = - (request.audio_type && authorizationFlags & WebContentsAdapterClient::MediaDesktopAudioCapture); - bool desktopVideoRequested = - (request.video_type && authorizationFlags & WebContentsAdapterClient::MediaDesktopVideoCapture); + WebContentsAdapterClient::MediaRequestFlags requestFlags = mediaRequestFlagsForRequest(request); + WebContentsAdapterClient::MediaRequestFlags finalFlags = requestFlags & authorizationFlags; + + bool microphoneRequested = finalFlags.testFlag(WebContentsAdapterClient::MediaAudioCapture); + bool webcamRequested = finalFlags.testFlag(WebContentsAdapterClient::MediaVideoCapture); + bool desktopAudioRequested = finalFlags.testFlag(WebContentsAdapterClient::MediaDesktopAudioCapture); + bool desktopVideoRequested = finalFlags.testFlag(WebContentsAdapterClient::MediaDesktopVideoCapture); if (securityOriginsMatch) { if (microphoneRequested || webcamRequested) { @@ -221,7 +231,8 @@ void MediaCaptureDevicesDispatcher::handleMediaAccessPermissionResponse(content: break; } } else if (desktopVideoRequested) { - getDevicesForDesktopCapture(&devices, getDefaultScreenId(), desktopAudioRequested); + getDevicesForDesktopCapture(&devices, getDefaultScreenId(), desktopAudioRequested, + request.video_type, request.audio_type); } } @@ -274,13 +285,13 @@ void MediaCaptureDevicesDispatcher::processMediaAccessRequest(WebContentsAdapter { DCHECK_CURRENTLY_ON(BrowserThread::UI); - // Let's not support tab capture for now. - if (request.video_type == blink::MEDIA_GUM_TAB_VIDEO_CAPTURE || request.audio_type == blink::MEDIA_GUM_TAB_AUDIO_CAPTURE) { + WebContentsAdapterClient::MediaRequestFlags flags = mediaRequestFlagsForRequest(request); + if (!flags) { std::move(callback).Run(blink::MediaStreamDevices(), blink::MEDIA_DEVICE_NOT_SUPPORTED, std::unique_ptr<content::MediaStreamUI>()); return; } - if (request.video_type == blink::MEDIA_GUM_DESKTOP_VIDEO_CAPTURE || request.audio_type == blink::MEDIA_GUM_DESKTOP_AUDIO_CAPTURE) { + if (flags.testFlag(WebContentsAdapterClient::MediaDesktopVideoCapture)) { const bool screenCaptureEnabled = adapterClient->webEngineSettings()->testAttribute(WebEngineSettings::ScreenCaptureEnabled); const bool originIsSecure = content::IsOriginSecure(request.security_origin); @@ -298,18 +309,13 @@ void MediaCaptureDevicesDispatcher::processMediaAccessRequest(WebContentsAdapter enqueueMediaAccessRequest(webContents, request, std::move(callback)); // We might not require this approval for pepper requests. - adapterClient->runMediaAccessPermissionRequest(toQt(request.security_origin), mediaRequestFlagsForRequest(request)); + adapterClient->runMediaAccessPermissionRequest(toQt(request.security_origin), flags); } void MediaCaptureDevicesDispatcher::processDesktopCaptureAccessRequest(content::WebContents *webContents, const content::MediaStreamRequest &request, content::MediaResponseCallback callback) { blink::MediaStreamDevices devices; - if (request.video_type != blink::MEDIA_GUM_DESKTOP_VIDEO_CAPTURE || request.requested_video_device_id.empty()) { - std::move(callback).Run(devices, blink::MEDIA_DEVICE_INVALID_STATE, std::unique_ptr<content::MediaStreamUI>()); - return; - } - content::WebContents *const web_contents_for_stream = content::WebContents::FromRenderFrameHost( content::RenderFrameHost::FromID(request.render_process_id, request.render_frame_id)); content::RenderFrameHost *const main_frame = web_contents_for_stream ? web_contents_for_stream->GetMainFrame() : NULL; @@ -334,7 +340,7 @@ void MediaCaptureDevicesDispatcher::processDesktopCaptureAccessRequest(content:: // Audio is only supported for screen capture streams. bool capture_audio = (mediaId.type == content::DesktopMediaID::TYPE_SCREEN && request.audio_type == blink::MEDIA_GUM_DESKTOP_AUDIO_CAPTURE); - getDevicesForDesktopCapture(&devices, mediaId, capture_audio); + getDevicesForDesktopCapture(&devices, mediaId, capture_audio, request.video_type, request.audio_type); std::move(callback).Run(devices, devices.empty() ? blink::MEDIA_DEVICE_INVALID_STATE : blink::MEDIA_DEVICE_OK, std::unique_ptr<content::MediaStreamUI>()); |