[MediaStream] Add screen capture IDL and stub functions
authoreric.carlson@apple.com <eric.carlson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 21 Dec 2017 02:45:36 +0000 (02:45 +0000)
committereric.carlson@apple.com <eric.carlson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 21 Dec 2017 02:45:36 +0000 (02:45 +0000)
https://bugs.webkit.org/show_bug.cgi?id=181070
<rdar://problem/35555184>

Reviewed by Youenn Fablet.

Source/WebCore:

Tests: fast/mediastream/screencapture-disabled.html
       fast/mediastream/screencapture-enabled.html

* Modules/mediastream/MediaDevices.cpp:
(WebCore::MediaDevices::getDisplayMedia const):
(WebCore::MediaDevices::getSupportedConstraints):
* Modules/mediastream/MediaDevices.h:
* Modules/mediastream/MediaDevices.idl:
* Modules/mediastream/MediaTrackConstraints.cpp:
(WebCore::convertToInternalForm):
* Modules/mediastream/MediaTrackConstraints.h:
* Modules/mediastream/MediaTrackConstraints.idl:
* Modules/mediastream/MediaTrackSupportedConstraints.h:
* Modules/mediastream/MediaTrackSupportedConstraints.idl:
* Modules/mediastream/UserMediaRequest.cpp:
(WebCore::UserMediaRequest::start):
(WebCore::UserMediaRequest::allow):
(WebCore::UserMediaRequest::deny):
* Modules/mediastream/UserMediaRequest.h:
* page/RuntimeEnabledFeatures.h:
(WebCore::RuntimeEnabledFeatures::screenCaptureEnabled const):
(WebCore::RuntimeEnabledFeatures::setScreenCaptureEnabled):
* platform/mediastream/CaptureDevice.h:
* platform/mediastream/MediaConstraints.cpp:
(WebCore::MediaTrackConstraintSetMap::set):
* platform/mediastream/MediaConstraints.h:
(WebCore::MediaTrackConstraintSetMap::displaySurface const):
(WebCore::MediaTrackConstraintSetMap::logicalSurface const):
(WebCore::MediaTrackConstraintSetMap::encode const):
(WebCore::MediaTrackConstraintSetMap::decode):
* platform/mediastream/MediaStreamRequest.h:
* platform/mediastream/RealtimeMediaSource.cpp:
(WebCore::RealtimeMediaSource::fitnessDistance):
(WebCore::RealtimeMediaSource::applyConstraint):
(WebCore::RealtimeMediaSource::supportsConstraint const):
* platform/mediastream/RealtimeMediaSourceCenter.cpp:
(WebCore::RealtimeMediaSourceCenter::validateRequestConstraints):
(WebCore::RealtimeMediaSourceCenter::captureDeviceWithPersistentID):
* platform/mediastream/RealtimeMediaSourceSettings.h:
(WebCore::RealtimeMediaSourceSettings::supportsDisplaySurface const):
(WebCore::RealtimeMediaSourceSettings::displaySurface const):
(WebCore::RealtimeMediaSourceSettings::setDisplaySurface):
(WebCore::RealtimeMediaSourceSettings::supportsLogicalSurface const):
(WebCore::RealtimeMediaSourceSettings::logicalSurface const):
(WebCore::RealtimeMediaSourceSettings::setLogicalSurface):
* platform/mediastream/RealtimeMediaSourceSupportedConstraints.cpp:
(WebCore::RealtimeMediaSourceSupportedConstraints::supportsConstraint const):
* platform/mediastream/RealtimeMediaSourceSupportedConstraints.h:
(WebCore::RealtimeMediaSourceSupportedConstraints::supportsDisplaySurface const):
(WebCore::RealtimeMediaSourceSupportedConstraints::setSupportsDisplaySurface):
(WebCore::RealtimeMediaSourceSupportedConstraints::supportsLogicalSurface const):
(WebCore::RealtimeMediaSourceSupportedConstraints::setSupportsLogicalSurface):
(WebCore::RealtimeMediaSourceSupportedConstraints::encode const):
(WebCore::RealtimeMediaSourceSupportedConstraints::decode):
* platform/mediastream/mac/RealtimeMediaSourceCenterMac.cpp:
* platform/mock/MockRealtimeVideoSource.cpp:
* testing/InternalSettings.cpp:
(WebCore::InternalSettings::Backup::Backup):
(WebCore::InternalSettings::Backup::restoreTo):
(WebCore::InternalSettings::setScreenCaptureEnabled):
* testing/InternalSettings.h:
* testing/InternalSettings.idl:

Source/WebKit:

* Shared/WebPreferences.yaml:
* UIProcess/API/Cocoa/WKPreferences.mm:
(-[WKPreferences _screenCaptureEnabled]):
(-[WKPreferences _setScreenCaptureEnabled:]):
* UIProcess/API/Cocoa/WKPreferencesPrivate.h:
* WebProcess/InjectedBundle/InjectedBundle.cpp:
(WebKit::InjectedBundle::overrideBoolPreferenceForTestRunner):

LayoutTests:

* fast/mediastream/screencapture-disabled-expected.txt: Added.
* fast/mediastream/screencapture-disabled.html: Added.
* fast/mediastream/screencapture-enabled-expected.txt: Added.
* fast/mediastream/screencapture-enabled.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@226211 268f45cc-cd09-0410-ab3c-d52691b4dbfc

36 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/mediastream/screencapture-disabled-expected.txt [new file with mode: 0644]
LayoutTests/fast/mediastream/screencapture-disabled.html [new file with mode: 0644]
LayoutTests/fast/mediastream/screencapture-enabled-expected.txt [new file with mode: 0644]
LayoutTests/fast/mediastream/screencapture-enabled.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/Modules/mediastream/MediaDevices.cpp
Source/WebCore/Modules/mediastream/MediaDevices.h
Source/WebCore/Modules/mediastream/MediaDevices.idl
Source/WebCore/Modules/mediastream/MediaTrackConstraints.cpp
Source/WebCore/Modules/mediastream/MediaTrackConstraints.h
Source/WebCore/Modules/mediastream/MediaTrackConstraints.idl
Source/WebCore/Modules/mediastream/MediaTrackSupportedConstraints.h
Source/WebCore/Modules/mediastream/MediaTrackSupportedConstraints.idl
Source/WebCore/Modules/mediastream/UserMediaRequest.cpp
Source/WebCore/Modules/mediastream/UserMediaRequest.h
Source/WebCore/page/RuntimeEnabledFeatures.h
Source/WebCore/platform/mediastream/CaptureDevice.h
Source/WebCore/platform/mediastream/MediaConstraints.cpp
Source/WebCore/platform/mediastream/MediaConstraints.h
Source/WebCore/platform/mediastream/MediaStreamRequest.h
Source/WebCore/platform/mediastream/RealtimeMediaSource.cpp
Source/WebCore/platform/mediastream/RealtimeMediaSourceCenter.cpp
Source/WebCore/platform/mediastream/RealtimeMediaSourceSettings.h
Source/WebCore/platform/mediastream/RealtimeMediaSourceSupportedConstraints.cpp
Source/WebCore/platform/mediastream/RealtimeMediaSourceSupportedConstraints.h
Source/WebCore/platform/mediastream/mac/RealtimeMediaSourceCenterMac.cpp
Source/WebCore/platform/mock/MockRealtimeVideoSource.cpp
Source/WebCore/testing/InternalSettings.cpp
Source/WebCore/testing/InternalSettings.h
Source/WebCore/testing/InternalSettings.idl
Source/WebKit/ChangeLog
Source/WebKit/Shared/WebPreferences.yaml
Source/WebKit/UIProcess/API/Cocoa/WKPreferences.mm
Source/WebKit/UIProcess/API/Cocoa/WKPreferencesPrivate.h
Source/WebKit/WebProcess/InjectedBundle/InjectedBundle.cpp

index 914b34d..ae38167 100644 (file)
@@ -1,3 +1,16 @@
+2017-12-20  Eric Carlson  <eric.carlson@apple.com>
+
+        [MediaStream] Add screen capture IDL and stub functions
+        https://bugs.webkit.org/show_bug.cgi?id=181070
+        <rdar://problem/35555184>
+
+        Reviewed by Youenn Fablet.
+
+        * fast/mediastream/screencapture-disabled-expected.txt: Added.
+        * fast/mediastream/screencapture-disabled.html: Added.
+        * fast/mediastream/screencapture-enabled-expected.txt: Added.
+        * fast/mediastream/screencapture-enabled.html: Added.
+
 2017-12-20  Matt Lewis  <jlewis3@apple.com>
 
         Unreviewed, rolling out r225656.
diff --git a/LayoutTests/fast/mediastream/screencapture-disabled-expected.txt b/LayoutTests/fast/mediastream/screencapture-disabled-expected.txt
new file mode 100644 (file)
index 0000000..dd5ed54
--- /dev/null
@@ -0,0 +1,2 @@
+PASS undefined is undefined.
+
diff --git a/LayoutTests/fast/mediastream/screencapture-disabled.html b/LayoutTests/fast/mediastream/screencapture-disabled.html
new file mode 100644 (file)
index 0000000..827eac4
--- /dev/null
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<script src="../../resources/js-test-pre.js"></script>
+<script>
+    if (window.testRunner)
+        window.testRunner.dumpAsText();
+
+    if (window.internals)
+        window.internals.settings.setScreenCaptureEnabled(false);
+
+    function runTest() {
+        if (!window.testRunner)
+            return;
+
+        shouldBeUndefined(navigator.mediaDevices.getDisplayMedia);
+    }
+
+    window.addEventListener("load", runTest, false);
+</script>
diff --git a/LayoutTests/fast/mediastream/screencapture-enabled-expected.txt b/LayoutTests/fast/mediastream/screencapture-enabled-expected.txt
new file mode 100644 (file)
index 0000000..773d018
--- /dev/null
@@ -0,0 +1,4 @@
+PASS function getDisplayMedia() {
+    [native code]
+} is defined.
+
diff --git a/LayoutTests/fast/mediastream/screencapture-enabled.html b/LayoutTests/fast/mediastream/screencapture-enabled.html
new file mode 100644 (file)
index 0000000..b8788c8
--- /dev/null
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<script src="../../resources/js-test-pre.js"></script>
+
+<script>
+    if (window.testRunner)
+        window.testRunner.dumpAsText();
+
+    if (window.internals)
+        window.internals.settings.setScreenCaptureEnabled(true);
+
+    function runTest() {
+        if (!window.testRunner)
+            return;
+
+        shouldBeDefined(navigator.mediaDevices.getDisplayMedia);
+    }
+
+    window.addEventListener("load", runTest, false);
+</script>
index 270adcf..07d3740 100644 (file)
@@ -1,3 +1,74 @@
+2017-12-20  Eric Carlson  <eric.carlson@apple.com>
+
+        [MediaStream] Add screen capture IDL and stub functions
+        https://bugs.webkit.org/show_bug.cgi?id=181070
+        <rdar://problem/35555184>
+
+        Reviewed by Youenn Fablet.
+
+        Tests: fast/mediastream/screencapture-disabled.html
+               fast/mediastream/screencapture-enabled.html
+
+        * Modules/mediastream/MediaDevices.cpp:
+        (WebCore::MediaDevices::getDisplayMedia const):
+        (WebCore::MediaDevices::getSupportedConstraints):
+        * Modules/mediastream/MediaDevices.h:
+        * Modules/mediastream/MediaDevices.idl:
+        * Modules/mediastream/MediaTrackConstraints.cpp:
+        (WebCore::convertToInternalForm):
+        * Modules/mediastream/MediaTrackConstraints.h:
+        * Modules/mediastream/MediaTrackConstraints.idl:
+        * Modules/mediastream/MediaTrackSupportedConstraints.h:
+        * Modules/mediastream/MediaTrackSupportedConstraints.idl:
+        * Modules/mediastream/UserMediaRequest.cpp:
+        (WebCore::UserMediaRequest::start):
+        (WebCore::UserMediaRequest::allow):
+        (WebCore::UserMediaRequest::deny):
+        * Modules/mediastream/UserMediaRequest.h:
+        * page/RuntimeEnabledFeatures.h:
+        (WebCore::RuntimeEnabledFeatures::screenCaptureEnabled const):
+        (WebCore::RuntimeEnabledFeatures::setScreenCaptureEnabled):
+        * platform/mediastream/CaptureDevice.h:
+        * platform/mediastream/MediaConstraints.cpp:
+        (WebCore::MediaTrackConstraintSetMap::set):
+        * platform/mediastream/MediaConstraints.h:
+        (WebCore::MediaTrackConstraintSetMap::displaySurface const):
+        (WebCore::MediaTrackConstraintSetMap::logicalSurface const):
+        (WebCore::MediaTrackConstraintSetMap::encode const):
+        (WebCore::MediaTrackConstraintSetMap::decode):
+        * platform/mediastream/MediaStreamRequest.h:
+        * platform/mediastream/RealtimeMediaSource.cpp:
+        (WebCore::RealtimeMediaSource::fitnessDistance):
+        (WebCore::RealtimeMediaSource::applyConstraint):
+        (WebCore::RealtimeMediaSource::supportsConstraint const):
+        * platform/mediastream/RealtimeMediaSourceCenter.cpp:
+        (WebCore::RealtimeMediaSourceCenter::validateRequestConstraints):
+        (WebCore::RealtimeMediaSourceCenter::captureDeviceWithPersistentID):
+        * platform/mediastream/RealtimeMediaSourceSettings.h:
+        (WebCore::RealtimeMediaSourceSettings::supportsDisplaySurface const):
+        (WebCore::RealtimeMediaSourceSettings::displaySurface const):
+        (WebCore::RealtimeMediaSourceSettings::setDisplaySurface):
+        (WebCore::RealtimeMediaSourceSettings::supportsLogicalSurface const):
+        (WebCore::RealtimeMediaSourceSettings::logicalSurface const):
+        (WebCore::RealtimeMediaSourceSettings::setLogicalSurface):
+        * platform/mediastream/RealtimeMediaSourceSupportedConstraints.cpp:
+        (WebCore::RealtimeMediaSourceSupportedConstraints::supportsConstraint const):
+        * platform/mediastream/RealtimeMediaSourceSupportedConstraints.h:
+        (WebCore::RealtimeMediaSourceSupportedConstraints::supportsDisplaySurface const):
+        (WebCore::RealtimeMediaSourceSupportedConstraints::setSupportsDisplaySurface):
+        (WebCore::RealtimeMediaSourceSupportedConstraints::supportsLogicalSurface const):
+        (WebCore::RealtimeMediaSourceSupportedConstraints::setSupportsLogicalSurface):
+        (WebCore::RealtimeMediaSourceSupportedConstraints::encode const):
+        (WebCore::RealtimeMediaSourceSupportedConstraints::decode):
+        * platform/mediastream/mac/RealtimeMediaSourceCenterMac.cpp:
+        * platform/mock/MockRealtimeVideoSource.cpp:
+        * testing/InternalSettings.cpp:
+        (WebCore::InternalSettings::Backup::Backup):
+        (WebCore::InternalSettings::Backup::restoreTo):
+        (WebCore::InternalSettings::setScreenCaptureEnabled):
+        * testing/InternalSettings.h:
+        * testing/InternalSettings.idl:
+
 2017-12-20  Matt Lewis  <jlewis3@apple.com>
 
         Unreviewed, rolling out r225656.
index 929d2db..d19bc77 100644 (file)
@@ -39,6 +39,7 @@
 #include "EventNames.h"
 #include "MediaDevicesRequest.h"
 #include "MediaTrackSupportedConstraints.h"
+#include "RuntimeEnabledFeatures.h"
 #include "UserMediaRequest.h"
 #include <wtf/RandomNumber.h>
 
@@ -108,6 +109,19 @@ ExceptionOr<void> MediaDevices::getUserMedia(const StreamConstraints& constraint
     return { };
 }
 
+ExceptionOr<void> MediaDevices::getDisplayMedia(const StreamConstraints& constraints, Promise&& promise) const
+{
+    auto* document = this->document();
+    if (!document)
+        return Exception { InvalidStateError };
+
+    auto request = UserMediaRequest::create(*document, { MediaStreamRequest::Type::DisplayMedia, createMediaConstraints(constraints.audio), createMediaConstraints(constraints.video) }, WTFMove(promise));
+    if (request)
+        request->start();
+
+    return { };
+}
+
 void MediaDevices::enumerateDevices(EnumerateDevicesPromise&& promise) const
 {
     auto* document = this->document();
@@ -131,6 +145,11 @@ MediaTrackSupportedConstraints MediaDevices::getSupportedConstraints()
     result.echoCancellation = supported.supportsEchoCancellation();
     result.deviceId = supported.supportsDeviceId();
     result.groupId = supported.supportsGroupId();
+    if (RuntimeEnabledFeatures::sharedFeatures().screenCaptureEnabled()) {
+        result.deviceId = supported.supportsDeviceId();
+        result.groupId = supported.supportsGroupId();
+    }
+
     return result;
 }
 
index 6112853..3d13964 100644 (file)
@@ -65,6 +65,7 @@ public:
         Variant<bool, MediaTrackConstraints> audio;
     };
     ExceptionOr<void> getUserMedia(const StreamConstraints&, Promise&&) const;
+    ExceptionOr<void> getDisplayMedia(const StreamConstraints&, Promise&&) const;
     void enumerateDevices(EnumerateDevicesPromise&&) const;
     MediaTrackSupportedConstraints getSupportedConstraints();
 
index abab178..6e476bc 100644 (file)
@@ -38,6 +38,7 @@
 
     MediaTrackSupportedConstraints getSupportedConstraints();
     [PrivateIdentifier, PublicIdentifier] Promise<MediaStream> getUserMedia(optional MediaStreamConstraints constraints);
+    [EnabledAtRuntime=ScreenCapture] Promise<MediaStream> getDisplayMedia(optional MediaStreamConstraints constraints);
 };
 
 [
index c4a3fca..9f10482 100644 (file)
@@ -171,6 +171,8 @@ static MediaTrackConstraintSetMap convertToInternalForm(ConstraintSetType setTyp
     // FIXME: add channelCount
     set(result, setType, "deviceId", MediaConstraintType::DeviceId, constraintSet.deviceId);
     set(result, setType, "groupId", MediaConstraintType::GroupId, constraintSet.groupId);
+    set(result, setType, "displaySurface", MediaConstraintType::DisplaySurface, constraintSet.displaySurface);
+    set(result, setType, "logicalSurface", MediaConstraintType::LogicalSurface, constraintSet.logicalSurface);
     return result;
 }
 
index 0395476..7314285 100644 (file)
@@ -73,6 +73,8 @@ struct MediaTrackConstraintSet {
     std::optional<ConstrainBoolean> echoCancellation;
     std::optional<ConstrainDOMString> deviceId;
     std::optional<ConstrainDOMString> groupId;
+    std::optional<ConstrainDOMString> displaySurface;
+    std::optional<ConstrainBoolean> logicalSurface;
 };
 
 struct MediaTrackConstraints : MediaTrackConstraintSet {
index a903983..ed2450d 100644 (file)
@@ -47,6 +47,9 @@
     // FIXME 169871: add channelCount
     ConstrainDOMString deviceId;
     ConstrainDOMString groupId;
+    ConstrainDOMString displaySurface;
+    ConstrainBoolean logicalSurface;
+
 };
 
 typedef (double or ConstrainDoubleRange) ConstrainDouble;
index f8626b8..dfc075f 100644 (file)
@@ -46,6 +46,8 @@ struct MediaTrackSupportedConstraints {
     bool echoCancellation;
     bool deviceId;
     bool groupId;
+    bool displaySurface;
+    bool logicalSurface;
 };
 
 } // namespace WebCore
index 5853728..e9cb1be 100644 (file)
@@ -45,4 +45,6 @@
     // FIXME 169871: add channelCount
     boolean deviceId = true;
     boolean groupId = true;
+    boolean displaySurface = true;
+    boolean logicalSurface = true;
 };
index 33de0b6..21e2c92 100644 (file)
@@ -159,10 +159,28 @@ void UserMediaRequest::start()
 {
     ASSERT(m_scriptExecutionContext);
     if (!m_scriptExecutionContext) {
-        deny(MediaAccessDenialReason::UserMediaDisabled, emptyString());
+        deny(MediaAccessDenialReason::UserMediaDisabled);
         return;
     }
 
+    if (m_request.type == MediaStreamRequest::Type::DisplayMedia) {
+        // https://w3c.github.io/mediacapture-screen-share/#constraints
+        // 5.2 Constraining Display Surface Selection
+        // The getDisplayMedia function does not permit the use of constraints for selection of a source as described
+        // in the getUserMedia() algorithm. Prior to invoking the getUserMedia() algorithm, if either of the video
+        // and audio attributes are set to a MediaTrackConstraints value (as opposed to being absent or set to a
+        // Boolean value), reject the promise with a InvalidAccessError and abort.
+        if (m_request.videoConstraints.isValid && !(m_request.videoConstraints.mandatoryConstraints.isEmpty() && m_request.videoConstraints.advancedConstraints.isEmpty())) {
+            deny(MediaAccessDenialReason::InvalidAccess);
+            return;
+        }
+
+        if (m_request.audioConstraints.isValid && !(m_request.audioConstraints.mandatoryConstraints.isEmpty() && m_request.audioConstraints.advancedConstraints.isEmpty())) {
+            deny(MediaAccessDenialReason::InvalidAccess);
+            return;
+        }
+    }
+
     // https://w3c.github.io/mediacapture-main/getusermedia.html#dom-mediadevices-getusermedia()
     // 1. Let constraints be the method's first argument.
     // 2. Let requestedMediaTypes be the set of media types in constraints with either a dictionary
@@ -171,7 +189,7 @@ void UserMediaRequest::start()
     //    "optional" occurs in the WebIDL due to WebIDL rules, but the argument must be supplied in order
     //    for the call to succeed.
     if (!m_request.audioConstraints.isValid && !m_request.videoConstraints.isValid) {
-        deny(MediaAccessDenialReason::NoConstraints, emptyString());
+        deny(MediaAccessDenialReason::NoConstraints);
         return;
     }
 
@@ -181,7 +199,7 @@ void UserMediaRequest::start()
     auto& document = downcast<Document>(*m_scriptExecutionContext);
     auto* controller = UserMediaController::from(document.page());
     if (!controller) {
-        deny(MediaAccessDenialReason::UserMediaDisabled, emptyString());
+        deny(MediaAccessDenialReason::UserMediaDisabled);
         return;
     }
 
@@ -192,7 +210,7 @@ void UserMediaRequest::start()
     //      the value NotAllowedError.
     String errorMessage;
     if (!canCallGetUserMedia(document, m_request.audioConstraints.isValid, m_request.videoConstraints.isValid, errorMessage)) {
-        deny(MediaAccessDenialReason::PermissionDenied, emptyString());
+        deny(MediaAccessDenialReason::PermissionDenied);
         document.domWindow()->printErrorMessage(errorMessage);
         return;
     }
@@ -209,14 +227,14 @@ void UserMediaRequest::allow(CaptureDevice&& audioDevice, CaptureDevice&& videoD
             return;
 
         if (!privateStream) {
-            deny(MediaAccessDenialReason::HardwareError, emptyString());
+            deny(MediaAccessDenialReason::HardwareError);
             return;
         }
         privateStream->monitorOrientation(downcast<Document>(m_scriptExecutionContext)->orientationNotifier());
 
         auto stream = MediaStream::create(*m_scriptExecutionContext, privateStream.releaseNonNull());
         if (stream->getTracks().isEmpty()) {
-            deny(MediaAccessDenialReason::HardwareError, emptyString());
+            deny(MediaAccessDenialReason::HardwareError);
             return;
         }
 
@@ -272,6 +290,10 @@ void UserMediaRequest::deny(MediaAccessDenialReason reason, const String& invali
         RELEASE_LOG(MediaStream, "UserMediaRequest::deny - permission denied");
         m_promise.reject(NotAllowedError);
         break;
+    case MediaAccessDenialReason::InvalidAccess:
+        RELEASE_LOG(MediaStream, "UserMediaRequest::deny - invalid access");
+        m_promise.reject(InvalidAccessError);
+        break;
     }
 }
 
index 8f9570b..6804da2 100644 (file)
@@ -56,8 +56,8 @@ public:
     WEBCORE_EXPORT void setAllowedMediaDeviceUIDs(const String& audioDeviceUID, const String& videoDeviceUID);
     WEBCORE_EXPORT void allow(CaptureDevice&& audioDevice, CaptureDevice&& videoDevice, String&& deviceIdentifierHashSalt);
 
-    enum MediaAccessDenialReason { NoConstraints, UserMediaDisabled, NoCaptureDevices, InvalidConstraint, HardwareError, PermissionDenied, OtherFailure };
-    WEBCORE_EXPORT void deny(MediaAccessDenialReason, const String& invalidConstraint);
+    enum MediaAccessDenialReason { NoConstraints, UserMediaDisabled, NoCaptureDevices, InvalidConstraint, HardwareError, PermissionDenied, InvalidAccess, OtherFailure };
+    WEBCORE_EXPORT void deny(MediaAccessDenialReason, const String& invalidConstraint = emptyString());
 
     const Vector<String>& audioDeviceUIDs() const { return m_audioDeviceUIDs; }
     const Vector<String>& videoDeviceUIDs() const { return m_videoDeviceUIDs; }
index be22f85..25a5121 100644 (file)
@@ -106,6 +106,8 @@ public:
     void setMediaDevicesEnabled(bool isEnabled) { m_isMediaDevicesEnabled = isEnabled; }
     bool mediaStreamEnabled() const { return m_isMediaStreamEnabled; }
     void setMediaStreamEnabled(bool isEnabled) { m_isMediaStreamEnabled = isEnabled; }
+    bool screenCaptureEnabled() const { return m_isScreenCaptureEnabled; }
+    void setScreenCaptureEnabled(bool isEnabled) { m_isScreenCaptureEnabled = isEnabled; }
 #endif
 
 #if ENABLE(WEB_RTC)
@@ -265,6 +267,7 @@ private:
 #if ENABLE(MEDIA_STREAM)
     bool m_isMediaDevicesEnabled { false };
     bool m_isMediaStreamEnabled { true };
+    bool m_isScreenCaptureEnabled { false };
 #endif
 
 #if ENABLE(WEB_RTC)
index 61277ce..dcc7ce0 100644 (file)
@@ -31,7 +31,7 @@ namespace WebCore {
 
 class CaptureDevice {
 public:
-    enum class DeviceType { Unknown, Microphone, Camera };
+    enum class DeviceType { Unknown, Microphone, Camera, Screen, Application, Window, Browser };
 
     CaptureDevice(const String& persistentId, DeviceType type, const String& label, const String& groupId = emptyString())
         : m_persistentId(persistentId)
index 01d291e..c90fbb0 100644 (file)
@@ -242,6 +242,8 @@ void MediaTrackConstraintSetMap::set(MediaConstraintType constraintType, std::op
     case MediaConstraintType::FacingMode:
     case MediaConstraintType::DeviceId:
     case MediaConstraintType::GroupId:
+    case MediaConstraintType::DisplaySurface:
+    case MediaConstraintType::LogicalSurface:
     case MediaConstraintType::Unknown:
         ASSERT_NOT_REACHED();
         break;
@@ -269,6 +271,8 @@ void MediaTrackConstraintSetMap::set(MediaConstraintType constraintType, std::op
     case MediaConstraintType::FacingMode:
     case MediaConstraintType::DeviceId:
     case MediaConstraintType::GroupId:
+    case MediaConstraintType::DisplaySurface:
+    case MediaConstraintType::LogicalSurface:
     case MediaConstraintType::Unknown:
         ASSERT_NOT_REACHED();
         break;
@@ -281,6 +285,12 @@ void MediaTrackConstraintSetMap::set(MediaConstraintType constraintType, std::op
     case MediaConstraintType::EchoCancellation:
         m_echoCancellation = WTFMove(constraint);
         break;
+    case MediaConstraintType::DisplaySurface:
+        m_displaySurface = WTFMove(constraint);
+        break;
+    case MediaConstraintType::LogicalSurface:
+        m_logicalSurface = WTFMove(constraint);
+        break;
 
     case MediaConstraintType::Width:
     case MediaConstraintType::Height:
@@ -319,6 +329,8 @@ void MediaTrackConstraintSetMap::set(MediaConstraintType constraintType, std::op
     case MediaConstraintType::FrameRate:
     case MediaConstraintType::Volume:
     case MediaConstraintType::EchoCancellation:
+    case MediaConstraintType::DisplaySurface:
+    case MediaConstraintType::LogicalSurface:
     case MediaConstraintType::Unknown:
         ASSERT_NOT_REACHED();
         break;
index 4c96969..41e0e76 100644 (file)
@@ -593,6 +593,8 @@ public:
     std::optional<DoubleConstraint> volume() const { return m_volume; }
 
     std::optional<BooleanConstraint> echoCancellation() const { return m_echoCancellation; }
+    std::optional<BooleanConstraint> displaySurface() const { return m_displaySurface; }
+    std::optional<BooleanConstraint> logicalSurface() const { return m_logicalSurface; }
 
     std::optional<StringConstraint> facingMode() const { return m_facingMode; }
     std::optional<StringConstraint> deviceId() const { return m_deviceId; }
@@ -610,6 +612,8 @@ public:
         encoder << m_volume;
 
         encoder << m_echoCancellation;
+        encoder << m_displaySurface;
+        encoder << m_logicalSurface;
 
         encoder << m_facingMode;
         encoder << m_deviceId;
@@ -637,6 +641,10 @@ public:
 
         if (!decoder.decode(map.m_echoCancellation))
             return std::nullopt;
+        if (!decoder.decode(map.m_displaySurface))
+            return std::nullopt;
+        if (!decoder.decode(map.m_logicalSurface))
+            return std::nullopt;
 
         if (!decoder.decode(map.m_facingMode))
             return std::nullopt;
@@ -659,6 +667,8 @@ private:
     std::optional<DoubleConstraint> m_volume;
 
     std::optional<BooleanConstraint> m_echoCancellation;
+    std::optional<BooleanConstraint> m_displaySurface;
+    std::optional<BooleanConstraint> m_logicalSurface;
 
     std::optional<StringConstraint> m_facingMode;
     std::optional<StringConstraint> m_deviceId;
index c5702c0..2804e89 100644 (file)
@@ -34,7 +34,7 @@
 namespace WebCore {
 
 struct MediaStreamRequest {
-    enum class Type { UserMedia };
+    enum class Type { UserMedia, DisplayMedia };
     Type type;
     MediaConstraints audioConstraints;
     MediaConstraints videoConstraints;
@@ -64,7 +64,7 @@ struct MediaStreamRequest {
 namespace WebCore {
 
 struct MediaStreamRequest {
-    enum class Type { UserMedia };
+    enum class Type { UserMedia, DisplayMedia };
     Type type;
 };
 
@@ -77,7 +77,8 @@ namespace WTF {
 template<> struct EnumTraits<WebCore::MediaStreamRequest> {
     using values = EnumValues<
         WebCore::MediaStreamRequest::Type,
-        WebCore::MediaStreamRequest::Type::UserMedia
+        WebCore::MediaStreamRequest::Type::UserMedia,
+        WebCore::MediaStreamRequest::Type::DisplayMedia
     >;
 };
 
index 6c03762..6c089d0 100644 (file)
@@ -361,10 +361,9 @@ double RealtimeMediaSource::fitnessDistance(const MediaConstraint& constraint)
         break;
     }
 
-    case MediaConstraintType::DeviceId: {
+    case MediaConstraintType::DeviceId:
         ASSERT_NOT_REACHED();
         break;
-    }
 
     case MediaConstraintType::GroupId: {
         ASSERT(constraint.isString());
@@ -375,6 +374,10 @@ double RealtimeMediaSource::fitnessDistance(const MediaConstraint& constraint)
         break;
     }
 
+    case MediaConstraintType::DisplaySurface:
+    case MediaConstraintType::LogicalSurface:
+        break;
+
     case MediaConstraintType::Unknown:
         // Unknown (or unsupported) constraints should be ignored.
         break;
@@ -514,6 +517,11 @@ void RealtimeMediaSource::applyConstraint(const MediaConstraint& constraint)
         // There is nothing to do here, neither can be changed.
         break;
 
+    case MediaConstraintType::DisplaySurface:
+    case MediaConstraintType::LogicalSurface:
+        ASSERT(constraint.isBoolean());
+        break;
+
     case MediaConstraintType::Unknown:
         break;
     }
@@ -705,6 +713,15 @@ bool RealtimeMediaSource::supportsConstraint(const MediaConstraint& constraint)
         return capabilities.supportsDeviceId();
         break;
 
+    case MediaConstraintType::DisplaySurface:
+    case MediaConstraintType::LogicalSurface:
+        // https://www.w3.org/TR/screen-capture/#new-constraints-for-captured-display-surfaces
+        // 5.2.1 New Constraints for Captured Display Surfaces
+        // Since the source of media cannot be changed after a MediaStreamTrack has been returned,
+        // these constraints cannot be changed by an application.
+        return false;
+        break;
+
     case MediaConstraintType::Unknown:
         // Unknown (or unsupported) constraints should be ignored.
         break;
index b81bbfe..8443445 100644 (file)
@@ -262,6 +262,14 @@ void RealtimeMediaSourceCenter::validateRequestConstraints(ValidConstraintsHandl
                     audioDeviceInfo.append({sourceOrError.captureSource->fitnessScore(), device});
             }
             break;
+        case CaptureDevice::DeviceType::Screen:
+        case CaptureDevice::DeviceType::Application:
+        case CaptureDevice::DeviceType::Window:
+        case CaptureDevice::DeviceType::Browser:
+            ASSERT(request.type == MediaStreamRequest::Type::DisplayMedia);
+            ASSERT(request.videoConstraints.mandatoryConstraints.isEmpty());
+            ASSERT(request.videoConstraints.advancedConstraints.isEmpty());
+            break;
         case CaptureDevice::DeviceType::Unknown:
             ASSERT_NOT_REACHED();
             break;
@@ -309,6 +317,10 @@ std::optional<CaptureDevice> RealtimeMediaSourceCenter::captureDeviceWithPersist
     case CaptureDevice::DeviceType::Microphone:
         return audioCaptureDeviceManager().captureDeviceWithPersistentID(type, id);
         break;
+    case CaptureDevice::DeviceType::Screen:
+    case CaptureDevice::DeviceType::Application:
+    case CaptureDevice::DeviceType::Window:
+    case CaptureDevice::DeviceType::Browser:
     case CaptureDevice::DeviceType::Unknown:
         ASSERT_NOT_REACHED();
         break;
index be56fb2..d69862d 100644 (file)
@@ -89,6 +89,14 @@ public:
     const AtomicString& groupId() const { return m_groupId; }
     void setGroupId(const AtomicString& groupId) { m_groupId = groupId; }
 
+    bool supportsDisplaySurface() const { return m_supportedConstraints.supportsDisplaySurface(); }
+    const AtomicString& displaySurface() const { return m_displaySurface; }
+    void setDisplaySurface(const AtomicString& displaySurface) { m_displaySurface = displaySurface; }
+
+    bool supportsLogicalSurface() const { return m_supportedConstraints.supportsLogicalSurface(); }
+    bool logicalSurface() const { return m_logicalSurface; }
+    void setLogicalSurface(bool logicalSurface) { m_logicalSurface = logicalSurface; }
+
     const RealtimeMediaSourceSupportedConstraints& supportedConstraints() const { return m_supportedConstraints; }
     void setSupportedConstraints(const RealtimeMediaSourceSupportedConstraints& supportedConstraints) { m_supportedConstraints = supportedConstraints; }
 
@@ -113,6 +121,9 @@ private:
     AtomicString m_groupId;
     AtomicString m_label;
 
+    AtomicString m_displaySurface;
+    bool m_logicalSurface { 0 };
+
     RealtimeMediaSourceSupportedConstraints m_supportedConstraints;
 };
 
index 57156d5..605d388 100644 (file)
@@ -61,6 +61,10 @@ bool RealtimeMediaSourceSupportedConstraints::supportsConstraint(MediaConstraint
         return supportsDeviceId();
     case MediaConstraintType::GroupId:
         return supportsGroupId();
+    case MediaConstraintType::DisplaySurface:
+        return supportsDisplaySurface();
+    case MediaConstraintType::LogicalSurface:
+        return supportsLogicalSurface();
     }
 
     ASSERT_NOT_REACHED();
index 4040e34..53f8e25 100644 (file)
@@ -49,7 +49,9 @@ enum class MediaConstraintType {
     SampleSize,
     EchoCancellation,
     DeviceId,
-    GroupId
+    GroupId,
+    DisplaySurface,
+    LogicalSurface,
 };
 
 class RealtimeMediaSourceSupportedConstraints {
@@ -91,6 +93,12 @@ public:
     bool supportsGroupId() const { return m_supportsGroupId; }
     void setSupportsGroupId(bool value) { m_supportsGroupId = value; }
 
+    bool supportsDisplaySurface() const { return m_supportsDisplaySurface; }
+    void setSupportsDisplaySurface(bool value) { m_supportsDisplaySurface = value; }
+
+    bool supportsLogicalSurface() const { return m_supportsLogicalSurface; }
+    void setSupportsLogicalSurface(bool value) { m_supportsLogicalSurface = value; }
+
     bool supportsConstraint(MediaConstraintType) const;
 
     template<class Encoder> void encode(Encoder&) const;
@@ -108,6 +116,8 @@ private:
     bool m_supportsEchoCancellation { false };
     bool m_supportsDeviceId { false };
     bool m_supportsGroupId { false };
+    bool m_supportsDisplaySurface { false };
+    bool m_supportsLogicalSurface { false };
 };
 
 template<class Encoder>
@@ -123,7 +133,9 @@ void RealtimeMediaSourceSupportedConstraints::encode(Encoder& encoder) const
         << m_supportsSampleSize
         << m_supportsEchoCancellation
         << m_supportsDeviceId
-        << m_supportsGroupId;
+        << m_supportsGroupId
+        << m_supportsDisplaySurface
+        << m_supportsLogicalSurface;
 }
 
 template<class Decoder>
@@ -139,7 +151,9 @@ bool RealtimeMediaSourceSupportedConstraints::decode(Decoder& decoder, RealtimeM
         && decoder.decode(constraints.m_supportsSampleSize)
         && decoder.decode(constraints.m_supportsEchoCancellation)
         && decoder.decode(constraints.m_supportsDeviceId)
-        && decoder.decode(constraints.m_supportsGroupId);
+        && decoder.decode(constraints.m_supportsGroupId)
+        && decoder.decode(constraints.m_supportsDisplaySurface)
+        && decoder.decode(constraints.m_supportsLogicalSurface);
 }
 
 } // namespace WebCore
index 386ce53..5ea7a93 100644 (file)
@@ -53,8 +53,13 @@ public:
         case CaptureDevice::DeviceType::Camera:
             return AVVideoCaptureSource::create(device.persistentId(), constraints);
             break;
+        
         case CaptureDevice::DeviceType::Microphone:
-        case CaptureDevice::DeviceType::Unknown:
+        case CaptureDevice::DeviceType::Screen:
+        case CaptureDevice::DeviceType::Application:
+        case CaptureDevice::DeviceType::Window:
+        case CaptureDevice::DeviceType::Browser:
+        case CaptureDevice::DeviceType::Unknown:        
             ASSERT_NOT_REACHED();
             break;
         }
index 1ec86bb..dba5a10 100644 (file)
@@ -60,6 +60,11 @@ public:
         case CaptureDevice::DeviceType::Camera:
             return MockRealtimeVideoSource::create(device.persistentId(), device.label(), constraints);
             break;
+
+        case CaptureDevice::DeviceType::Screen:
+        case CaptureDevice::DeviceType::Application:
+        case CaptureDevice::DeviceType::Window:
+        case CaptureDevice::DeviceType::Browser:
         case CaptureDevice::DeviceType::Microphone:
         case CaptureDevice::DeviceType::Unknown:
             ASSERT_NOT_REACHED();
index cdabb6f..7004f0d 100644 (file)
@@ -112,6 +112,9 @@ InternalSettings::Backup::Backup(Settings& settings)
     , m_webGPUEnabled(RuntimeEnabledFeatures::sharedFeatures().webGPUEnabled())
 #endif
     , m_webVREnabled(RuntimeEnabledFeatures::sharedFeatures().webVREnabled())
+#if ENABLE(MEDIA_STREAM)
+    , m_setScreenCaptureEnabled(RuntimeEnabledFeatures::sharedFeatures().screenCaptureEnabled())
+#endif
     , m_shouldMockBoldSystemFontForAccessibility(RenderTheme::singleton().shouldMockBoldSystemFontForAccessibility())
 #if USE(AUDIO_SESSION)
     , m_shouldManageAudioSessionCategory(DeprecatedGlobalSettings::shouldManageAudioSessionCategory())
@@ -210,6 +213,9 @@ void InternalSettings::Backup::restoreTo(Settings& settings)
     RuntimeEnabledFeatures::sharedFeatures().setWebGPUEnabled(m_webGPUEnabled);
 #endif
     RuntimeEnabledFeatures::sharedFeatures().setWebVREnabled(m_webVREnabled);
+#if ENABLE(MEDIA_STREAM)
+    RuntimeEnabledFeatures::sharedFeatures().setScreenCaptureEnabled(m_setScreenCaptureEnabled);
+#endif
 
 #if USE(AUDIO_SESSION)
     DeprecatedGlobalSettings::setShouldManageAudioSessionCategory(m_shouldManageAudioSessionCategory);
@@ -762,6 +768,15 @@ void InternalSettings::setWebVREnabled(bool enabled)
     RuntimeEnabledFeatures::sharedFeatures().setWebVREnabled(enabled);
 }
 
+void InternalSettings::setScreenCaptureEnabled(bool enabled)
+{
+#if ENABLE(MEDIA_STREAM)
+    RuntimeEnabledFeatures::sharedFeatures().setScreenCaptureEnabled(enabled);
+#else
+    UNUSED_PARAM(enabled);
+#endif
+}
+
 ExceptionOr<String> InternalSettings::userInterfaceDirectionPolicy()
 {
     if (!m_page)
index ab6412b..7d77ff5 100644 (file)
@@ -123,6 +123,7 @@ public:
     static void setWebGL2Enabled(bool);
     static void setWebGPUEnabled(bool);
     static void setWebVREnabled(bool);
+    static void setScreenCaptureEnabled(bool);
 
 private:
     explicit InternalSettings(Page*);
@@ -203,6 +204,7 @@ private:
         bool m_webGL2Enabled;
         bool m_webGPUEnabled;
         bool m_webVREnabled;
+        bool m_setScreenCaptureEnabled;
         
         bool m_shouldMockBoldSystemFontForAccessibility;
 #if USE(AUDIO_SESSION)
index 11bb9c7..d07e66e 100644 (file)
@@ -92,6 +92,7 @@ enum FontLoadTimingOverride { "Block", "Swap", "Failure" };
     void setWebGL2Enabled(boolean enabled);
     void setWebGPUEnabled(boolean enabled);
     void setWebVREnabled(boolean enabled);
+    void setScreenCaptureEnabled(boolean enabled);
 
     [MayThrowException] DOMString userInterfaceDirectionPolicy();
     [MayThrowException] void setUserInterfaceDirectionPolicy(DOMString policy);
index a1e72a9..0f22126 100644 (file)
@@ -1,3 +1,19 @@
+2017-12-20  Eric Carlson  <eric.carlson@apple.com>
+
+        [MediaStream] Add screen capture IDL and stub functions
+        https://bugs.webkit.org/show_bug.cgi?id=181070
+        <rdar://problem/35555184>
+
+        Reviewed by Youenn Fablet.
+
+        * Shared/WebPreferences.yaml:
+        * UIProcess/API/Cocoa/WKPreferences.mm:
+        (-[WKPreferences _screenCaptureEnabled]):
+        (-[WKPreferences _setScreenCaptureEnabled:]):
+        * UIProcess/API/Cocoa/WKPreferencesPrivate.h:
+        * WebProcess/InjectedBundle/InjectedBundle.cpp:
+        (WebKit::InjectedBundle::overrideBoolPreferenceForTestRunner):
+
 2017-12-20  Youenn Fablet  <youenn@apple.com>
 
         Crash when clearing std::optional<WebKit::WebServiceWorkerFetchTaskClient::BlobLoader>
index 5452435..9b5f4f2 100644 (file)
@@ -486,6 +486,12 @@ MediaStreamEnabled:
   webcoreBinding: RuntimeEnabledFeatures
   condition: ENABLE(MEDIA_STREAM)
 
+ScreenCaptureEnabled:
+  type: bool
+  defaultValue: false
+  webcoreBinding: RuntimeEnabledFeatures
+  condition: ENABLE(MEDIA_STREAM)
+
 PeerConnectionEnabled:
   type: bool
   defaultValue: WebCore::LibWebRTCProvider::webRTCAvailable()
index cf692cc..f215ad6 100644 (file)
@@ -582,6 +582,16 @@ static _WKStorageBlockingPolicy toAPI(WebCore::SecurityOrigin::StorageBlockingPo
     _preferences->setMediaDevicesEnabled(enabled);
 }
 
+- (BOOL)_screenCaptureEnabled
+{
+    return _preferences->screenCaptureEnabled();
+}
+
+- (void)_setScreenCaptureEnabled:(BOOL)enabled
+{
+    _preferences->setScreenCaptureEnabled(enabled);
+}
+
 - (BOOL)_mockCaptureDevicesEnabled
 {
     return _preferences->mockCaptureDevicesEnabled();
index 6a18806..c3c0dba 100644 (file)
@@ -104,6 +104,7 @@ typedef NS_OPTIONS(NSUInteger, _WKJavaScriptRuntimeFlags) {
 
 @property (nonatomic, setter=_setPeerConnectionEnabled:) BOOL _peerConnectionEnabled WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA));
 @property (nonatomic, setter=_setMediaDevicesEnabled:) BOOL _mediaDevicesEnabled WK_API_AVAILABLE(macosx(10.13), ios(11.0));
+@property (nonatomic, setter=_setScreenCaptureEnabled:) BOOL _screenCaptureEnabled WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_MAC_TBA));
 @property (nonatomic, setter=_setMockCaptureDevicesEnabled:) BOOL _mockCaptureDevicesEnabled WK_API_AVAILABLE(macosx(10.13), ios(11.0));
 @property (nonatomic, setter=_setMockCaptureDevicesPromptEnabled:) BOOL _mockCaptureDevicesPromptEnabled WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA));
 @property (nonatomic, setter=_setMediaCaptureRequiresSecureConnection:) BOOL _mediaCaptureRequiresSecureConnection WK_API_AVAILABLE(macosx(10.13), ios(11.0));
index 7a54795..aead25d 100644 (file)
@@ -224,6 +224,8 @@ void InjectedBundle::overrideBoolPreferenceForTestRunner(WebPageGroupProxy* page
 #if ENABLE(MEDIA_STREAM)
     if (preference == "WebKitMediaDevicesEnabled")
         RuntimeEnabledFeatures::sharedFeatures().setMediaDevicesEnabled(enabled);
+    if (preference == "WebKitScreenCaptureEnabled")
+        RuntimeEnabledFeatures::sharedFeatures().setScreenCaptureEnabled(enabled);
 #endif
 
 #if ENABLE(WEB_RTC)