diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/core/media_capture_devices_dispatcher.cpp | 204 | ||||
-rw-r--r-- | src/core/media_capture_devices_dispatcher.h | 2 | ||||
-rw-r--r-- | src/core/web_contents_adapter_client.h | 2 | ||||
-rw-r--r-- | src/webengine/api/qquickwebengineview.cpp | 20 | ||||
-rw-r--r-- | src/webengine/api/qquickwebengineview_p.h | 4 | ||||
-rw-r--r-- | src/webengine/doc/src/webengineview.qdoc | 5 | ||||
-rw-r--r-- | src/webengine/plugin/plugin.cpp | 1 | ||||
-rw-r--r-- | src/webengine/plugin/plugins.qmltypes | 10 | ||||
-rw-r--r-- | src/webenginewidgets/api/qwebenginepage.cpp | 99 | ||||
-rw-r--r-- | src/webenginewidgets/api/qwebenginepage.h | 4 | ||||
-rw-r--r-- | src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc | 5 |
11 files changed, 198 insertions, 158 deletions
diff --git a/src/core/media_capture_devices_dispatcher.cpp b/src/core/media_capture_devices_dispatcher.cpp index 8bdbaadd2..04d4a1924 100644 --- a/src/core/media_capture_devices_dispatcher.cpp +++ b/src/core/media_capture_devices_dispatcher.cpp @@ -121,13 +121,51 @@ std::unique_ptr<content::MediaStreamUI> getDevicesForDesktopCapture(content::Med return std::move(ui); } +content::DesktopMediaID getDefaultScreenId() +{ +#if BUILDFLAG(ENABLE_WEBRTC) + // Source id patterns are different across platforms. + // On Linux, the hardcoded value "0" is used. + // On Windows, the screens are enumerated consecutively in increasing order from 0. + // On macOS the source ids are randomish numbers assigned by the OS. + + // In order to provide a correct screen id, we query for the available screen ids, and + // select the first one as the main display id. + // The code is based on the file + // src/chrome/browser/extensions/api/desktop_capture/desktop_capture_base.cc. + webrtc::DesktopCaptureOptions options = + webrtc::DesktopCaptureOptions::CreateDefault(); + options.set_disable_effects(false); + std::unique_ptr<webrtc::DesktopCapturer> screen_capturer( + webrtc::DesktopCapturer::CreateScreenCapturer(options)); + + if (screen_capturer) { + webrtc::DesktopCapturer::SourceList screens; + if (screen_capturer->GetSourceList(&screens)) { + if (screens.size() > 0) { + return content::DesktopMediaID(content::DesktopMediaID::TYPE_SCREEN, screens[0].id); + } + } + } +#endif + + return content::DesktopMediaID(content::DesktopMediaID::TYPE_SCREEN, 0); +} + WebContentsAdapterClient::MediaRequestFlags mediaRequestFlagsForRequest(const content::MediaStreamRequest &request) { WebContentsAdapterClient::MediaRequestFlags requestFlags = WebContentsAdapterClient::MediaNone; + if (request.audio_type == content::MEDIA_DEVICE_AUDIO_CAPTURE) requestFlags |= WebContentsAdapterClient::MediaAudioCapture; + else if (request.audio_type == content::MEDIA_DESKTOP_AUDIO_CAPTURE) + requestFlags |= WebContentsAdapterClient::MediaDesktopAudioCapture; + if (request.video_type == content::MEDIA_DEVICE_VIDEO_CAPTURE) requestFlags |= WebContentsAdapterClient::MediaVideoCapture; + else if (request.video_type == content::MEDIA_DESKTOP_VIDEO_CAPTURE) + requestFlags |= WebContentsAdapterClient::MediaDesktopVideoCapture; + return requestFlags; } @@ -150,6 +188,7 @@ void MediaCaptureDevicesDispatcher::handleMediaAccessPermissionResponse(content: { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + std::unique_ptr<content::MediaStreamUI> ui; content::MediaStreamDevices devices; std::map<content::WebContents*, RequestsQueue>::iterator it = m_pendingRequests.find(webContents); @@ -176,16 +215,30 @@ void MediaCaptureDevicesDispatcher::handleMediaAccessPermissionResponse(content: (request.audio_type && authorizationFlags & WebContentsAdapterClient::MediaAudioCapture); bool webcamRequested = (request.video_type && authorizationFlags & WebContentsAdapterClient::MediaVideoCapture); - if (securityOriginsMatch && (microphoneRequested || webcamRequested)) { - switch (request.request_type) { - case content::MEDIA_OPEN_DEVICE_PEPPER_ONLY: - getDefaultDevices("", "", microphoneRequested, webcamRequested, &devices); - break; - case content::MEDIA_DEVICE_ACCESS: - case content::MEDIA_GENERATE_STREAM: - getDefaultDevices(request.requested_audio_device_id, request.requested_video_device_id, - microphoneRequested, webcamRequested, &devices); - break; + bool desktopAudioRequested = + (request.audio_type && authorizationFlags & WebContentsAdapterClient::MediaDesktopAudioCapture); + bool desktopVideoRequested = + (request.video_type && authorizationFlags & WebContentsAdapterClient::MediaDesktopVideoCapture); + + if (securityOriginsMatch) { + if (microphoneRequested || webcamRequested) { + switch (request.request_type) { + case content::MEDIA_OPEN_DEVICE_PEPPER_ONLY: + getDefaultDevices("", "", microphoneRequested, webcamRequested, &devices); + break; + case content::MEDIA_DEVICE_ACCESS: + case content::MEDIA_GENERATE_STREAM: + getDefaultDevices(request.requested_audio_device_id, request.requested_video_device_id, + microphoneRequested, webcamRequested, &devices); + break; + } + } else if (desktopVideoRequested) { + ui = getDevicesForDesktopCapture( + &devices, + getDefaultScreenId(), + desktopAudioRequested, + /* display_notification: */ false, + getContentsUrl(webContents)); } } @@ -200,7 +253,7 @@ void MediaCaptureDevicesDispatcher::handleMediaAccessPermissionResponse(content: BrowserThread::UI, FROM_HERE, base::Bind(&MediaCaptureDevicesDispatcher::ProcessQueuedAccessRequest, base::Unretained(this), webContents)); } - callback.Run(devices, devices.empty() ? content::MEDIA_DEVICE_INVALID_STATE : content::MEDIA_DEVICE_OK, std::unique_ptr<content::MediaStreamUI>()); + callback.Run(devices, devices.empty() ? content::MEDIA_DEVICE_INVALID_STATE : content::MEDIA_DEVICE_OK, std::move(ui)); } @@ -238,22 +291,34 @@ void MediaCaptureDevicesDispatcher::processMediaAccessRequest(WebContentsAdapter , const content::MediaStreamRequest &request , const content::MediaResponseCallback &callback) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - // Let's not support tab capture for now. - if (request.video_type == content::MEDIA_TAB_VIDEO_CAPTURE || request.audio_type == content::MEDIA_TAB_AUDIO_CAPTURE) - return; - - if (request.video_type == content::MEDIA_DESKTOP_VIDEO_CAPTURE || request.audio_type == content::MEDIA_DESKTOP_AUDIO_CAPTURE) - // It's still unclear what to make of screen capture. We can rely on existing javascript dialog infrastructure - // to experiment with this without exposing it through our API yet. - processDesktopCaptureAccessRequest(webContents, request, callback); - else { - enqueueMediaAccessRequest(webContents, request, callback); - // We might not require this approval for pepper requests. - adapterClient->runMediaAccessPermissionRequest(toQt(request.security_origin), mediaRequestFlagsForRequest(request)); - } + // Let's not support tab capture for now. + if (request.video_type == content::MEDIA_TAB_VIDEO_CAPTURE || request.audio_type == content::MEDIA_TAB_AUDIO_CAPTURE) { + callback.Run(content::MediaStreamDevices(), content::MEDIA_DEVICE_NOT_SUPPORTED, std::unique_ptr<content::MediaStreamUI>()); + return; + } + + if (request.video_type == content::MEDIA_DESKTOP_VIDEO_CAPTURE || + request.audio_type == content::MEDIA_DESKTOP_AUDIO_CAPTURE) { + const bool screenCaptureEnabled = + adapterClient->webEngineSettings()->testAttribute(WebEngineSettings::ScreenCaptureEnabled); + const bool originIsSecure = content::IsOriginSecure(request.security_origin); + if (!screenCaptureEnabled || !originIsSecure) { + callback.Run(content::MediaStreamDevices(), content::MEDIA_DEVICE_INVALID_STATE, std::unique_ptr<content::MediaStreamUI>()); + return; + } + if (!request.requested_video_device_id.empty()) { + // Non-empty device id from the chooseDesktopMedia() extension API. + processDesktopCaptureAccessRequest(webContents, request, callback); + return; + } + } + + enqueueMediaAccessRequest(webContents, request, callback); + // We might not require this approval for pepper requests. + adapterClient->runMediaAccessPermissionRequest(toQt(request.security_origin), mediaRequestFlagsForRequest(request)); } void MediaCaptureDevicesDispatcher::processDesktopCaptureAccessRequest(content::WebContents *webContents, const content::MediaStreamRequest &request @@ -262,19 +327,12 @@ void MediaCaptureDevicesDispatcher::processDesktopCaptureAccessRequest(content:: content::MediaStreamDevices devices; std::unique_ptr<content::MediaStreamUI> ui; - if (request.video_type != content::MEDIA_DESKTOP_VIDEO_CAPTURE) { + if (request.video_type != content::MEDIA_DESKTOP_VIDEO_CAPTURE || + request.requested_video_device_id.empty()) { callback.Run(devices, content::MEDIA_DEVICE_INVALID_STATE, std::move(ui)); return; } - // If the device id wasn't specified then this is a screen capture request - // (i.e. chooseDesktopMedia() API wasn't used to generate device id). - if (request.requested_video_device_id.empty()) { - processScreenCaptureAccessRequest( - webContents, request, callback); - 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; @@ -307,84 +365,6 @@ void MediaCaptureDevicesDispatcher::processDesktopCaptureAccessRequest(content:: callback.Run(devices, devices.empty() ? content::MEDIA_DEVICE_INVALID_STATE : content::MEDIA_DEVICE_OK, std::move(ui)); } -void MediaCaptureDevicesDispatcher::processScreenCaptureAccessRequest(content::WebContents *webContents, const content::MediaStreamRequest &request - ,const content::MediaResponseCallback &callback) -{ - DCHECK_EQ(request.video_type, content::MEDIA_DESKTOP_VIDEO_CAPTURE); - - WebContentsAdapterClient *adapterClient = WebContentsViewQt::from(static_cast<content::WebContentsImpl*>(webContents)->GetView())->client(); - const bool screenCaptureEnabled = adapterClient->webEngineSettings()->testAttribute(WebEngineSettings::ScreenCaptureEnabled); - - const bool originIsSecure = content::IsOriginSecure(request.security_origin); - - if (screenCaptureEnabled && originIsSecure) { - - enqueueMediaAccessRequest(webContents, request, callback); - base::Callback<void(bool, const base::string16&)> dialogCallback = base::Bind(&MediaCaptureDevicesDispatcher::handleScreenCaptureAccessRequest, - base::Unretained(this), base::Unretained(webContents)); - - QUrl securityOrigin(toQt(request.security_origin)); - QString message = QCoreApplication::translate("MediaCaptureDevicesDispatcher", "Do you want %1 to share your screen?").arg(securityOrigin.toString()); - QString title = QCoreApplication::translate("MediaCaptureDevicesDispatcher", "%1 Screen Sharing request").arg(securityOrigin.toString()); - JavaScriptDialogManagerQt::GetInstance()->runDialogForContents(webContents, WebContentsAdapterClient::InternalAuthorizationDialog, message - , QString(), securityOrigin, dialogCallback, title); - } else - callback.Run(content::MediaStreamDevices(), content::MEDIA_DEVICE_INVALID_STATE, std::unique_ptr<content::MediaStreamUI>()); -} - -void MediaCaptureDevicesDispatcher::handleScreenCaptureAccessRequest(content::WebContents *webContents, bool userAccepted, const base::string16 &) -{ - content::MediaStreamDevices devices; - std::unique_ptr<content::MediaStreamUI> ui; -#if BUILDFLAG(ENABLE_WEBRTC) - if (userAccepted) { - // Source id patterns are different across platforms. - // On Linux, the hardcoded value "0" is used. - // On Windows, the screens are enumerated consecutively in increasing order from 0. - // On macOS the source ids are randomish numbers assigned by the OS. - webrtc::DesktopCapturer::SourceId id = 0; - - // In order to provide a correct screen id, we query for the available screen ids, and - // select the first one as the main display id. - // The code is based on the file - // src/chrome/browser/extensions/api/desktop_capture/desktop_capture_base.cc. - webrtc::DesktopCaptureOptions options = - webrtc::DesktopCaptureOptions::CreateDefault(); - options.set_disable_effects(false); - std::unique_ptr<webrtc::DesktopCapturer> screen_capturer( - webrtc::DesktopCapturer::CreateScreenCapturer(options)); - - if (screen_capturer) { - webrtc::DesktopCapturer::SourceList screens; - if (screen_capturer->GetSourceList(&screens)) { - if (screens.size() > 0) { - id = screens[0].id; - } - } - } - - content::DesktopMediaID screenId = content::DesktopMediaID( - content::DesktopMediaID::TYPE_SCREEN, id); - ui = getDevicesForDesktopCapture(&devices, screenId, false/*capture_audio*/, false/*display_notification*/, getContentsUrl(webContents)); - } -#endif - std::map<content::WebContents*, RequestsQueue>::iterator it = - m_pendingRequests.find(webContents); - if (it == m_pendingRequests.end()) { - // WebContents has been destroyed. Don't need to do anything. - return; - } - - RequestsQueue &queue(it->second); - if (queue.empty()) - return; - - content::MediaResponseCallback callback = queue.front().callback; - queue.pop_front(); - - callback.Run(devices, devices.empty() ? content::MEDIA_DEVICE_INVALID_STATE : content::MEDIA_DEVICE_OK, std::move(ui)); -} - void MediaCaptureDevicesDispatcher::enqueueMediaAccessRequest(content::WebContents *webContents, const content::MediaStreamRequest &request ,const content::MediaResponseCallback &callback) { diff --git a/src/core/media_capture_devices_dispatcher.h b/src/core/media_capture_devices_dispatcher.h index c378c327e..579d159a4 100644 --- a/src/core/media_capture_devices_dispatcher.h +++ b/src/core/media_capture_devices_dispatcher.h @@ -116,8 +116,6 @@ class MediaCaptureDevicesDispatcher : public content::MediaObserver, // Helpers for ProcessMediaAccessRequest(). void processDesktopCaptureAccessRequest(content::WebContents *, const content::MediaStreamRequest &, const content::MediaResponseCallback &); - void processScreenCaptureAccessRequest(content::WebContents *,const content::MediaStreamRequest &, const content::MediaResponseCallback &); - void handleScreenCaptureAccessRequest(content::WebContents *, bool userAccepted, const base::string16 &/*unused callback_input*/); void enqueueMediaAccessRequest(content::WebContents *, const content::MediaStreamRequest &, const content::MediaResponseCallback &); void ProcessQueuedAccessRequest(content::WebContents *); diff --git a/src/core/web_contents_adapter_client.h b/src/core/web_contents_adapter_client.h index 8d75f24b7..8b7365342 100644 --- a/src/core/web_contents_adapter_client.h +++ b/src/core/web_contents_adapter_client.h @@ -316,6 +316,8 @@ public: MediaNone = 0, MediaAudioCapture = 0x01, MediaVideoCapture = 0x02, + MediaDesktopAudioCapture = 0x04, + MediaDesktopVideoCapture = 0x08 }; Q_DECLARE_FLAGS(MediaRequestFlags, MediaRequestFlag) diff --git a/src/webengine/api/qquickwebengineview.cpp b/src/webengine/api/qquickwebengineview.cpp index c5c772411..09f22c280 100644 --- a/src/webengine/api/qquickwebengineview.cpp +++ b/src/webengine/api/qquickwebengineview.cpp @@ -703,8 +703,13 @@ void QQuickWebEngineViewPrivate::runMediaAccessPermissionRequest(const QUrl &sec feature = QQuickWebEngineView::MediaAudioVideoCapture; else if (requestFlags.testFlag(WebContentsAdapterClient::MediaAudioCapture)) feature = QQuickWebEngineView::MediaAudioCapture; - else // WebContentsAdapterClient::MediaVideoCapture + else if (requestFlags.testFlag(WebContentsAdapterClient::MediaVideoCapture)) feature = QQuickWebEngineView::MediaVideoCapture; + else if (requestFlags.testFlag(WebContentsAdapterClient::MediaDesktopAudioCapture) && + requestFlags.testFlag(WebContentsAdapterClient::MediaDesktopVideoCapture)) + feature = QQuickWebEngineView::DesktopAudioVideoCapture; + else // if (requestFlags.testFlag(WebContentsAdapterClient::MediaDesktopVideoCapture)) + feature = QQuickWebEngineView::DesktopVideoCapture; Q_EMIT q->featurePermissionRequested(securityOrigin, feature); } @@ -1431,7 +1436,8 @@ void QQuickWebEngineView::grantFeaturePermission(const QUrl &securityOrigin, QQu { if (!d_ptr->adapter) return; - if (!granted && feature >= MediaAudioCapture && feature <= MediaAudioVideoCapture) { + if (!granted && ((feature >= MediaAudioCapture && feature <= MediaAudioVideoCapture) || + (feature >= DesktopVideoCapture && feature <= DesktopAudioVideoCapture))) { d_ptr->adapter->grantMediaAccessPermission(securityOrigin, WebContentsAdapterClient::MediaNone); return; } @@ -1449,6 +1455,16 @@ void QQuickWebEngineView::grantFeaturePermission(const QUrl &securityOrigin, QQu case Geolocation: d_ptr->adapter->runGeolocationRequestCallback(securityOrigin, granted); break; + case DesktopVideoCapture: + d_ptr->adapter->grantMediaAccessPermission(securityOrigin, WebContentsAdapterClient::MediaDesktopVideoCapture); + break; + case DesktopAudioVideoCapture: + d_ptr->adapter->grantMediaAccessPermission( + securityOrigin, + WebContentsAdapterClient::MediaRequestFlags( + WebContentsAdapterClient::MediaDesktopAudioCapture | + WebContentsAdapterClient::MediaDesktopVideoCapture)); + break; default: Q_UNREACHABLE(); } diff --git a/src/webengine/api/qquickwebengineview_p.h b/src/webengine/api/qquickwebengineview_p.h index 32419329a..ae0523460 100644 --- a/src/webengine/api/qquickwebengineview_p.h +++ b/src/webengine/api/qquickwebengineview_p.h @@ -199,7 +199,9 @@ public: MediaAudioCapture, MediaVideoCapture, MediaAudioVideoCapture, - Geolocation + Geolocation, + DesktopVideoCapture, + DesktopAudioVideoCapture }; Q_ENUM(Feature) diff --git a/src/webengine/doc/src/webengineview.qdoc b/src/webengine/doc/src/webengineview.qdoc index e452746d9..1d1c61f03 100644 --- a/src/webengine/doc/src/webengineview.qdoc +++ b/src/webengine/doc/src/webengineview.qdoc @@ -850,6 +850,11 @@ Video devices, such as cameras. \value WebEngineView.MediaAudioVideoCapture Both audio and video capture devices. + \value DesktopVideoCapture + Video output capture, that is, the capture of the user's display. + (Added in Qt 5.10) + \value DesktopAudioVideoCapture + Both audio and video output capture. (Added in Qt 5.10) \sa featurePermissionRequested(), grantFeaturePermission() */ diff --git a/src/webengine/plugin/plugin.cpp b/src/webengine/plugin/plugin.cpp index e58b2ab61..5ab792699 100644 --- a/src/webengine/plugin/plugin.cpp +++ b/src/webengine/plugin/plugin.cpp @@ -85,6 +85,7 @@ public: qmlRegisterType<QQuickWebEngineView, 3>(uri, 1, 3, "WebEngineView"); qmlRegisterType<QQuickWebEngineView, 4>(uri, 1, 4, "WebEngineView"); qmlRegisterType<QQuickWebEngineView, 5>(uri, 1, 5, "WebEngineView"); + qmlRegisterType<QQuickWebEngineView, 6>(uri, 1, 6, "WebEngineView"); qmlRegisterType<QQuickWebEngineProfile>(uri, 1, 1, "WebEngineProfile"); qmlRegisterType<QQuickWebEngineProfile, 1>(uri, 1, 2, "WebEngineProfile"); qmlRegisterType<QQuickWebEngineProfile, 2>(uri, 1, 3, "WebEngineProfile"); diff --git a/src/webengine/plugin/plugins.qmltypes b/src/webengine/plugin/plugins.qmltypes index 0cfa2d25b..321c462b5 100644 --- a/src/webengine/plugin/plugins.qmltypes +++ b/src/webengine/plugin/plugins.qmltypes @@ -576,9 +576,10 @@ Module { "QtWebEngine/WebEngineView 1.2", "QtWebEngine/WebEngineView 1.3", "QtWebEngine/WebEngineView 1.4", - "QtWebEngine/WebEngineView 1.5" + "QtWebEngine/WebEngineView 1.5", + "QtWebEngine/WebEngineView 1.6" ] - exportMetaObjectRevisions: [0, 1, 2, 3, 4, 5] + exportMetaObjectRevisions: [0, 1, 2, 3, 4, 5, 6] Enum { name: "NavigationRequestAction" values: { @@ -633,7 +634,9 @@ Module { "MediaAudioCapture": 0, "MediaVideoCapture": 1, "MediaAudioVideoCapture": 2, - "Geolocation": 3 + "Geolocation": 3, + "DesktopVideoCapture": 4, + "DesktopAudioVideoCapture": 5 } } Enum { @@ -889,6 +892,7 @@ Module { Property { name: "audioMuted"; revision: 3; type: "bool" } Property { name: "recentlyAudible"; revision: 3; type: "bool"; isReadonly: true } Property { name: "webChannelWorld"; revision: 3; type: "uint" } + Property { name: "testSupport"; type: "QQuickWebEngineTestSupport"; isPointer: true } Signal { name: "loadingChanged" Parameter { name: "loadRequest"; type: "QQuickWebEngineLoadRequest"; isPointer: true } diff --git a/src/webenginewidgets/api/qwebenginepage.cpp b/src/webenginewidgets/api/qwebenginepage.cpp index 87af187e3..5b7fa9df2 100644 --- a/src/webenginewidgets/api/qwebenginepage.cpp +++ b/src/webenginewidgets/api/qwebenginepage.cpp @@ -560,16 +560,20 @@ void QWebEnginePagePrivate::showColorDialog(QSharedPointer<ColorChooserControlle void QWebEnginePagePrivate::runMediaAccessPermissionRequest(const QUrl &securityOrigin, WebContentsAdapterClient::MediaRequestFlags requestFlags) { Q_Q(QWebEnginePage); - QWebEnginePage::Feature requestedFeature; - if (requestFlags.testFlag(WebContentsAdapterClient::MediaAudioCapture) && requestFlags.testFlag(WebContentsAdapterClient::MediaVideoCapture)) - requestedFeature = QWebEnginePage::MediaAudioVideoCapture; + QWebEnginePage::Feature feature; + if (requestFlags.testFlag(WebContentsAdapterClient::MediaAudioCapture) && + requestFlags.testFlag(WebContentsAdapterClient::MediaVideoCapture)) + feature = QWebEnginePage::MediaAudioVideoCapture; else if (requestFlags.testFlag(WebContentsAdapterClient::MediaAudioCapture)) - requestedFeature = QWebEnginePage::MediaAudioCapture; + feature = QWebEnginePage::MediaAudioCapture; else if (requestFlags.testFlag(WebContentsAdapterClient::MediaVideoCapture)) - requestedFeature = QWebEnginePage::MediaVideoCapture; - else - return; - Q_EMIT q->featurePermissionRequested(securityOrigin, requestedFeature); + feature = QWebEnginePage::MediaVideoCapture; + else if (requestFlags.testFlag(WebContentsAdapterClient::MediaDesktopAudioCapture) && + requestFlags.testFlag(WebContentsAdapterClient::MediaDesktopVideoCapture)) + feature = QWebEnginePage::DesktopAudioVideoCapture; + else // if (requestFlags.testFlag(WebContentsAdapterClient::MediaDesktopVideoCapture)) + feature = QWebEnginePage::DesktopVideoCapture; + Q_EMIT q->featurePermissionRequested(securityOrigin, feature); } void QWebEnginePagePrivate::runGeolocationPermissionRequest(const QUrl &securityOrigin) @@ -1728,37 +1732,58 @@ void QWebEnginePage::setFeaturePermission(const QUrl &securityOrigin, QWebEngine Q_D(QWebEnginePage); if (policy == PermissionUnknown) return; - WebContentsAdapterClient::MediaRequestFlags flags = WebContentsAdapterClient::MediaNone; - switch (feature) { - case MediaAudioVideoCapture: - case MediaAudioCapture: - case MediaVideoCapture: - if (policy != PermissionUnknown) { - if (policy == PermissionDeniedByUser) - flags = WebContentsAdapterClient::MediaNone; - else { - if (feature == MediaAudioCapture) - flags = WebContentsAdapterClient::MediaAudioCapture; - else if (feature == MediaVideoCapture) - flags = WebContentsAdapterClient::MediaVideoCapture; - else - flags = WebContentsAdapterClient::MediaRequestFlags(WebContentsAdapterClient::MediaVideoCapture | WebContentsAdapterClient::MediaAudioCapture); - } - d->adapter->grantMediaAccessPermission(securityOrigin, flags); - } - d->adapter->grantMediaAccessPermission(securityOrigin, flags); - break; - case QWebEnginePage::Geolocation: - d->adapter->runGeolocationRequestCallback(securityOrigin, (policy == PermissionGrantedByUser) ? true : false); - break; - case MouseLock: - if (policy == PermissionGrantedByUser) + + const WebContentsAdapterClient::MediaRequestFlags audioVideoCaptureFlags( + WebContentsAdapterClient::MediaVideoCapture | + WebContentsAdapterClient::MediaAudioCapture); + const WebContentsAdapterClient::MediaRequestFlags desktopAudioVideoCaptureFlags( + WebContentsAdapterClient::MediaDesktopVideoCapture | + WebContentsAdapterClient::MediaDesktopAudioCapture); + + if (policy == PermissionGrantedByUser) { + switch (feature) { + case MediaAudioVideoCapture: + d->adapter->grantMediaAccessPermission(securityOrigin, audioVideoCaptureFlags); + break; + case MediaAudioCapture: + d->adapter->grantMediaAccessPermission(securityOrigin, WebContentsAdapterClient::MediaAudioCapture); + break; + case MediaVideoCapture: + d->adapter->grantMediaAccessPermission(securityOrigin, WebContentsAdapterClient::MediaVideoCapture); + break; + case DesktopAudioVideoCapture: + d->adapter->grantMediaAccessPermission(securityOrigin, desktopAudioVideoCaptureFlags); + break; + case DesktopVideoCapture: + d->adapter->grantMediaAccessPermission(securityOrigin, WebContentsAdapterClient::MediaDesktopVideoCapture); + break; + case Geolocation: + d->adapter->runGeolocationRequestCallback(securityOrigin, true); + break; + case MouseLock: d->adapter->grantMouseLockPermission(true); - else + break; + case Notifications: + break; + } + } else { // if (policy == PermissionDeniedByUser) + switch (feature) { + case MediaAudioVideoCapture: + case MediaAudioCapture: + case MediaVideoCapture: + case DesktopAudioVideoCapture: + case DesktopVideoCapture: + d->adapter->grantMediaAccessPermission(securityOrigin, WebContentsAdapterClient::MediaNone); + break; + case Geolocation: + d->adapter->runGeolocationRequestCallback(securityOrigin, false); + break; + case MouseLock: d->adapter->grantMouseLockPermission(false); - break; - case Notifications: - break; + break; + case Notifications: + break; + } } } diff --git a/src/webenginewidgets/api/qwebenginepage.h b/src/webenginewidgets/api/qwebenginepage.h index 74ebd0a35..292075827 100644 --- a/src/webenginewidgets/api/qwebenginepage.h +++ b/src/webenginewidgets/api/qwebenginepage.h @@ -188,7 +188,9 @@ public: MediaAudioCapture = 2, MediaVideoCapture, MediaAudioVideoCapture, - MouseLock + MouseLock, + DesktopVideoCapture, + DesktopAudioVideoCapture }; Q_ENUM(Feature) diff --git a/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc b/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc index 621982951..3b9300a4b 100644 --- a/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc +++ b/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc @@ -286,6 +286,11 @@ \value MouseLock Mouse locking, which locks the mouse pointer to the web view and is typically used in games. + \value DesktopVideoCapture + Video output capture, that is, the capture of the user's display, + for screen sharing purposes for example. (Added in Qt 5.10) + \value DesktopAudioVideoCapture + Both audio and video output capture. (Added in Qt 5.10) \sa featurePermissionRequested(), featurePermissionRequestCanceled(), setFeaturePermission(), PermissionPolicy |