Title: [216545] trunk
Revision
216545
Author
eric.carl...@apple.com
Date
2017-05-09 15:06:13 -0700 (Tue, 09 May 2017)

Log Message

[MediaStream] deviceId constraint doesn't work with getUserMedia
https://bugs.webkit.org/show_bug.cgi?id=171877
<rdar://problem/31899730>

Reviewed by Jer Noble.

Source/WebCore:

Test: fast/mediastream/get-user-media-device-id.html

* Modules/mediastream/MediaConstraintsImpl.h:
(WebCore::MediaConstraintsData::MediaConstraintsData): Add a constructor that
takes a const MediaConstraints&.

* Modules/mediastream/MediaDevicesEnumerationRequest.cpp:
(WebCore::MediaDevicesEnumerationRequest::topLevelDocumentOrigin): Don't return
NULL for the main frame so the origin matches that returned for a UserMediaRequest.

* Modules/mediastream/UserMediaController.h:
(WebCore::UserMediaController::setDeviceIDHashSalt): Deleted, not used.
(WebCore::UserMediaController::deviceIDHashSalt): Deleted, not used.

* Modules/mediastream/UserMediaRequest.cpp:
(WebCore::UserMediaRequest::allow): Add device ID hash salt parameter, set it on
constraints.
* Modules/mediastream/UserMediaRequest.h:

* platform/mediastream/MediaConstraints.h:
* platform/mediastream/RealtimeMediaSource.cpp:
(WebCore::RealtimeMediaSource::fitnessDistance): ASSERT if called for DeviceId.
(WebCore::RealtimeMediaSource::selectSettings): Special case DeviceId because it
we have to hash the device ID before comparing, and because the DeviceId can't be
changed so it should never be added to the flattened constraints.

* platform/mediastream/RealtimeMediaSourceSupportedConstraints.cpp:
(WebCore::RealtimeMediaSourceSupportedConstraints::nameForConstraint): Deleted, unused.
(WebCore::RealtimeMediaSourceSupportedConstraints::constraintFromName): Deleted, unused.
* platform/mediastream/RealtimeMediaSourceSupportedConstraints.h:

* platform/mediastream/mac/AVVideoCaptureSource.mm:
* platform/mediastream/mac/RealtimeMediaSourceCenterMac.cpp:
(WebCore::RealtimeMediaSourceCenterMac::bestSourcesForTypeAndConstraints): Pass device
id, not empty string.

Source/WebKit2:

* Shared/WebCoreArgumentCoders.cpp:
(IPC::ArgumentCoder<MediaConstraintsData>::encode): Encode deviceIDHashSalt.
(IPC::ArgumentCoder<MediaConstraintsData>::decode): Decode deviceIDHashSalt.

* UIProcess/UserMediaPermissionCheckProxy.cpp:
(WebKit::UserMediaPermissionCheckProxy::UserMediaPermissionCheckProxy): Initialize
completion handler, frame ID, and security origins.
(WebKit::UserMediaPermissionCheckProxy::setUserMediaAccessInfo): Complete by calling
completion handler because we now sometimes request access info before calling gUM.
(WebKit::UserMediaPermissionCheckProxy::invalidate): Clear completion handler.
* UIProcess/UserMediaPermissionCheckProxy.h:

* UIProcess/UserMediaPermissionRequestManagerProxy.cpp:
(WebKit::FrameAuthorizationState::FrameAuthorizationState): Take security origins, not
UserMediaPermissionRequestProxy, so it can be constructed with a UserMediaPermissionCheckProxy.
(WebKit::FrameAuthorizationState::ensureSecurityOriginsAreEqual): Ditto. Clear has salt
when origins don't match.
(WebKit::UserMediaPermissionRequestManagerProxy::stateForRequest): Templatize.
(WebKit::UserMediaPermissionRequestManagerProxy::userMediaAccessWasDenied): Fix typo.
(WebKit::UserMediaPermissionRequestManagerProxy::userMediaAccessWasGranted): Ditto.
Don't set state for empty UIDs. Pass hash salt to web process.
(WebKit::UserMediaPermissionRequestManagerProxy::requestUserMediaPermissionForFrame):
The device ID hash salt is now required to validate constraints, so get it first.
(WebKit::UserMediaPermissionRequestManagerProxy::getUserMediaPermissionInfo): Helper
method used to get the device ID hash salt.
(WebKit::UserMediaPermissionRequestManagerProxy::enumerateMediaDevicesForFrame): Restructure
to use getUserMediaPermissionInfo.
(WebKit::UserMediaPermissionRequestManagerProxy::didCompleteUserMediaPermissionCheck): Deleted.
* UIProcess/UserMediaPermissionRequestManagerProxy.h:

* WebProcess/MediaStream/UserMediaPermissionRequestManager.cpp:
(WebKit::UserMediaPermissionRequestManager::userMediaAccessWasGranted): Add device ID
hash salt parameter.
* WebProcess/MediaStream/UserMediaPermissionRequestManager.h:

* WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::userMediaAccessWasGranted): Ditto.
* WebProcess/WebPage/WebPage.h:
* WebProcess/WebPage/WebPage.messages.in:

* WebProcess/cocoa/UserMediaCaptureManager.cpp:
(WebKit::UserMediaCaptureManager::createCaptureSource): Use new MediaConstraintsData
constructor.

LayoutTests:

* fast/mediastream/get-user-media-device-id-expected.txt: Added.
* fast/mediastream/get-user-media-device-id.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (216544 => 216545)


--- trunk/LayoutTests/ChangeLog	2017-05-09 21:52:53 UTC (rev 216544)
+++ trunk/LayoutTests/ChangeLog	2017-05-09 22:06:13 UTC (rev 216545)
@@ -1,3 +1,14 @@
+2017-05-09  Eric Carlson  <eric.carl...@apple.com>
+
+        [MediaStream] deviceId constraint doesn't work with getUserMedia
+        https://bugs.webkit.org/show_bug.cgi?id=171877
+        <rdar://problem/31899730>
+
+        Reviewed by Jer Noble.
+
+        * fast/mediastream/get-user-media-device-id-expected.txt: Added.
+        * fast/mediastream/get-user-media-device-id.html: Added.
+
 2017-05-09  Matt Lewis  <jlew...@apple.com>
 
         Marked multiple test flaky.

Added: trunk/LayoutTests/fast/mediastream/get-user-media-device-id-expected.txt (0 => 216545)


--- trunk/LayoutTests/fast/mediastream/get-user-media-device-id-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/mediastream/get-user-media-device-id-expected.txt	2017-05-09 22:06:13 UTC (rev 216545)
@@ -0,0 +1,5 @@
+
+PASS Collect device IDs 
+PASS Pass device IDs as exact constraints 
+PASS Pass device IDs as optional constraints 
+

Added: trunk/LayoutTests/fast/mediastream/get-user-media-device-id.html (0 => 216545)


--- trunk/LayoutTests/fast/mediastream/get-user-media-device-id.html	                        (rev 0)
+++ trunk/LayoutTests/fast/mediastream/get-user-media-device-id.html	2017-05-09 22:06:13 UTC (rev 216545)
@@ -0,0 +1,56 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="utf-8">
+    <title>Test passing capture device IDs to getUserMedia</title>
+    <script src=""
+    <script src=""
+    <script>
+    let deviceIds = [];
+
+    if (window.testRunner)
+        testRunner.setUserMediaPermission(true);
+
+    promise_test((test) => {
+        return navigator.mediaDevices.enumerateDevices()
+            .then((devices) => {
+                devices.forEach((device) => {
+                    let kind = device.kind == "audioinput" ? "audio" : "video";
+                    deviceIds.push({ type: kind, id : device.deviceId});
+                });
+            });
+    }, "Collect device IDs");
+    
+    let constraints = { };
+
+    promise_test((test) => {
+        deviceIds.forEach((info) => {
+            constraints[info.type] = { deviceId: { exact: info.id } };
+        });
+    
+        return navigator.mediaDevices.getUserMedia(constraints)
+            .then((stream) => {
+                assert_equals(stream.getAudioTracks().length, 1, "correct number of audio tracks");
+                assert_equals(stream.getVideoTracks().length, 1, "correct number of audio tracks");
+            })
+
+    }, "Pass device IDs as exact constraints");
+    
+    promise_test((test) => {
+        deviceIds.forEach((info) => {
+            constraints[info.type] = { deviceId: info.id };
+        });
+    
+        return navigator.mediaDevices.getUserMedia(constraints)
+            .then((stream) => {
+                assert_equals(stream.getAudioTracks().length, 1, "correct number of audio tracks");
+                assert_equals(stream.getVideoTracks().length, 1, "correct number of audio tracks");
+            })
+
+    }, "Pass device IDs as optional constraints");
+
+    </script>
+</head>
+<body>
+</body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (216544 => 216545)


--- trunk/Source/WebCore/ChangeLog	2017-05-09 21:52:53 UTC (rev 216544)
+++ trunk/Source/WebCore/ChangeLog	2017-05-09 22:06:13 UTC (rev 216545)
@@ -1,3 +1,47 @@
+2017-05-09  Eric Carlson  <eric.carl...@apple.com>
+
+        [MediaStream] deviceId constraint doesn't work with getUserMedia
+        https://bugs.webkit.org/show_bug.cgi?id=171877
+        <rdar://problem/31899730>
+
+        Reviewed by Jer Noble.
+
+        Test: fast/mediastream/get-user-media-device-id.html
+
+        * Modules/mediastream/MediaConstraintsImpl.h:
+        (WebCore::MediaConstraintsData::MediaConstraintsData): Add a constructor that 
+        takes a const MediaConstraints&.
+
+        * Modules/mediastream/MediaDevicesEnumerationRequest.cpp:
+        (WebCore::MediaDevicesEnumerationRequest::topLevelDocumentOrigin): Don't return
+        NULL for the main frame so the origin matches that returned for a UserMediaRequest.
+
+        * Modules/mediastream/UserMediaController.h:
+        (WebCore::UserMediaController::setDeviceIDHashSalt): Deleted, not used.
+        (WebCore::UserMediaController::deviceIDHashSalt): Deleted, not used.
+
+        * Modules/mediastream/UserMediaRequest.cpp:
+        (WebCore::UserMediaRequest::allow): Add device ID hash salt parameter, set it on
+        constraints.
+        * Modules/mediastream/UserMediaRequest.h:
+
+        * platform/mediastream/MediaConstraints.h:
+        * platform/mediastream/RealtimeMediaSource.cpp:
+        (WebCore::RealtimeMediaSource::fitnessDistance): ASSERT if called for DeviceId.
+        (WebCore::RealtimeMediaSource::selectSettings): Special case DeviceId because it
+        we have to hash the device ID before comparing, and because the DeviceId can't be
+        changed so it should never be added to the flattened constraints.
+
+        * platform/mediastream/RealtimeMediaSourceSupportedConstraints.cpp:
+        (WebCore::RealtimeMediaSourceSupportedConstraints::nameForConstraint): Deleted, unused.
+        (WebCore::RealtimeMediaSourceSupportedConstraints::constraintFromName): Deleted, unused.
+        * platform/mediastream/RealtimeMediaSourceSupportedConstraints.h:
+
+        * platform/mediastream/mac/AVVideoCaptureSource.mm:
+        * platform/mediastream/mac/RealtimeMediaSourceCenterMac.cpp:
+        (WebCore::RealtimeMediaSourceCenterMac::bestSourcesForTypeAndConstraints): Pass device
+        id, not empty string.
+
 2017-05-09  Antoine Quint  <grao...@apple.com>
 
         [Modern Media Controls] Localized strings aren't loaded

Modified: trunk/Source/WebCore/Modules/mediastream/MediaConstraintsImpl.h (216544 => 216545)


--- trunk/Source/WebCore/Modules/mediastream/MediaConstraintsImpl.h	2017-05-09 21:52:53 UTC (rev 216544)
+++ trunk/Source/WebCore/Modules/mediastream/MediaConstraintsImpl.h	2017-05-09 22:06:13 UTC (rev 216545)
@@ -46,6 +46,20 @@
         , isValid(isValid)
     {
     }
+    MediaConstraintsData(const MediaConstraints& constraints)
+        : mandatoryConstraints(constraints.mandatoryConstraints())
+        , advancedConstraints(constraints.advancedConstraints())
+        , deviceIDHashSalt(constraints.deviceIDHashSalt())
+        , isValid(constraints.isValid())
+    {
+    }
+    MediaConstraintsData(const MediaConstraintsData& constraints, const String& hashSalt)
+        : mandatoryConstraints(constraints.mandatoryConstraints)
+        , advancedConstraints(constraints.advancedConstraints)
+        , deviceIDHashSalt(hashSalt)
+        , isValid(constraints.isValid)
+    {
+    }
 
     void setDefaultVideoConstraints();
     bool isConstraintSet(std::function<bool(const MediaTrackConstraintSetMap&)>&&);
@@ -52,6 +66,7 @@
 
     MediaTrackConstraintSetMap mandatoryConstraints;
     Vector<MediaTrackConstraintSetMap> advancedConstraints;
+    String deviceIDHashSalt;
     bool isValid { false };
 };
 
@@ -66,8 +81,11 @@
     const MediaTrackConstraintSetMap& mandatoryConstraints() const final { return m_data.mandatoryConstraints; }
     const Vector<MediaTrackConstraintSetMap>& advancedConstraints() const final { return m_data.advancedConstraints; }
     bool isValid() const final { return m_data.isValid; }
+
+    String deviceIDHashSalt() const final { return m_data.deviceIDHashSalt; }
+    void setDeviceIDHashSalt(const String& salt) final { m_data.deviceIDHashSalt = salt; }
+
     const MediaConstraintsData& data() const { return m_data; }
-
     void setDefaultVideoConstraints() { m_data.setDefaultVideoConstraints(); }
 
 private:

Modified: trunk/Source/WebCore/Modules/mediastream/MediaDevicesEnumerationRequest.cpp (216544 => 216545)


--- trunk/Source/WebCore/Modules/mediastream/MediaDevicesEnumerationRequest.cpp	2017-05-09 21:52:53 UTC (rev 216544)
+++ trunk/Source/WebCore/Modules/mediastream/MediaDevicesEnumerationRequest.cpp	2017-05-09 22:06:13 UTC (rev 216545)
@@ -65,11 +65,6 @@
     if (!scriptExecutionContext())
         return nullptr;
 
-    if (Frame* frame = downcast<Document>(*scriptExecutionContext()).frame()) {
-        if (frame->isMainFrame())
-            return nullptr;
-    }
-
     return &scriptExecutionContext()->topOrigin();
 }
 

Modified: trunk/Source/WebCore/Modules/mediastream/UserMediaController.h (216544 => 216545)


--- trunk/Source/WebCore/Modules/mediastream/UserMediaController.h	2017-05-09 21:52:53 UTC (rev 216544)
+++ trunk/Source/WebCore/Modules/mediastream/UserMediaController.h	2017-05-09 22:06:13 UTC (rev 216545)
@@ -46,15 +46,11 @@
     void enumerateMediaDevices(MediaDevicesEnumerationRequest&);
     void cancelMediaDevicesEnumerationRequest(MediaDevicesEnumerationRequest&);
 
-    void setDeviceIDHashSalt(const String& salt) { m_idHashSalt = salt; }
-    String deviceIDHashSalt() const { return m_idHashSalt; }
-
     WEBCORE_EXPORT static const char* supplementName();
     static UserMediaController* from(Page* page) { return static_cast<UserMediaController*>(Supplement<Page>::from(page, supplementName())); }
 
 private:
     UserMediaClient* m_client;
-    String m_idHashSalt;
 };
 
 inline void UserMediaController::requestUserMediaAccess(UserMediaRequest& request)

Modified: trunk/Source/WebCore/Modules/mediastream/UserMediaRequest.cpp (216544 => 216545)


--- trunk/Source/WebCore/Modules/mediastream/UserMediaRequest.cpp	2017-05-09 21:52:53 UTC (rev 216544)
+++ trunk/Source/WebCore/Modules/mediastream/UserMediaRequest.cpp	2017-05-09 22:06:13 UTC (rev 216545)
@@ -153,7 +153,7 @@
     m_controller->requestUserMediaAccess(*this);
 }
 
-void UserMediaRequest::allow(const String& audioDeviceUID, const String& videoDeviceUID)
+void UserMediaRequest::allow(const String& audioDeviceUID, const String& videoDeviceUID, const String& deviceIdentifierHashSalt)
 {
     m_allowedAudioDeviceUID = audioDeviceUID;
     m_allowedVideoDeviceUID = videoDeviceUID;
@@ -180,6 +180,9 @@
         m_promise.resolve(stream);
     };
 
+    m_audioConstraints->setDeviceIDHashSalt(deviceIdentifierHashSalt);
+    m_videoConstraints->setDeviceIDHashSalt(deviceIdentifierHashSalt);
+
     RealtimeMediaSourceCenter::singleton().createMediaStream(WTFMove(callback), m_allowedAudioDeviceUID, m_allowedVideoDeviceUID, &m_audioConstraints.get(), &m_videoConstraints.get());
 }
 

Modified: trunk/Source/WebCore/Modules/mediastream/UserMediaRequest.h (216544 => 216545)


--- trunk/Source/WebCore/Modules/mediastream/UserMediaRequest.h	2017-05-09 21:52:53 UTC (rev 216544)
+++ trunk/Source/WebCore/Modules/mediastream/UserMediaRequest.h	2017-05-09 22:06:13 UTC (rev 216545)
@@ -53,7 +53,7 @@
     void start();
 
     WEBCORE_EXPORT void setAllowedMediaDeviceUIDs(const String& audioDeviceUID, const String& videoDeviceUID);
-    WEBCORE_EXPORT void allow(const String& audioDeviceUID, const String& videoDeviceUID);
+    WEBCORE_EXPORT void allow(const String& audioDeviceUID, const String& videoDeviceUID, const String& deviceIdentifierHashSalt);
 
     enum MediaAccessDenialReason { NoConstraints, UserMediaDisabled, NoCaptureDevices, InvalidConstraint, HardwareError, PermissionDenied, OtherFailure };
     WEBCORE_EXPORT void deny(MediaAccessDenialReason, const String& invalidConstraint);

Modified: trunk/Source/WebCore/platform/mediastream/MediaConstraints.h (216544 => 216545)


--- trunk/Source/WebCore/platform/mediastream/MediaConstraints.h	2017-05-09 21:52:53 UTC (rev 216544)
+++ trunk/Source/WebCore/platform/mediastream/MediaConstraints.h	2017-05-09 22:06:13 UTC (rev 216545)
@@ -811,6 +811,9 @@
     virtual const Vector<MediaTrackConstraintSetMap>& advancedConstraints() const = 0;
     virtual bool isValid() const = 0;
 
+    virtual String deviceIDHashSalt() const = 0;
+    virtual void setDeviceIDHashSalt(const String&) = 0;
+
 protected:
     MediaConstraints() { }
 };

Modified: trunk/Source/WebCore/platform/mediastream/RealtimeMediaSource.cpp (216544 => 216545)


--- trunk/Source/WebCore/platform/mediastream/RealtimeMediaSource.cpp	2017-05-09 21:52:53 UTC (rev 216544)
+++ trunk/Source/WebCore/platform/mediastream/RealtimeMediaSource.cpp	2017-05-09 22:06:13 UTC (rev 216545)
@@ -39,6 +39,7 @@
 #include "MediaConstraints.h"
 #include "NotImplemented.h"
 #include "RealtimeMediaSourceCapabilities.h"
+#include "RealtimeMediaSourceCenter.h"
 #include <wtf/MainThread.h>
 #include <wtf/UUID.h>
 #include <wtf/text/StringHash.h>
@@ -341,11 +342,7 @@
     }
 
     case MediaConstraintType::DeviceId: {
-        ASSERT(constraint.isString());
-        if (!capabilities.supportsDeviceId())
-            return 0;
-
-        return downcast<StringConstraint>(constraint).fitnessDistance(m_id);
+        ASSERT_NOT_REACHED();
         break;
     }
 
@@ -541,6 +538,23 @@
             return false;
         }
 
+        // The deviceId can't be changed, and the constraint value is the hashed device ID, so verify that the
+        // device's unique ID hashes to the constraint value but don't include the constraint in the flattened
+        // constraint set.
+        if (constraint.constraintType() == MediaConstraintType::DeviceId) {
+            ASSERT(constraint.isString());
+            ASSERT(!constraints.deviceIDHashSalt().isEmpty());
+
+            auto hashedID = RealtimeMediaSourceCenter::singleton().hashStringWithSalt(m_persistentID, constraints.deviceIDHashSalt());
+            double constraintDistance = downcast<StringConstraint>(constraint).fitnessDistance(hashedID);
+            if (std::isinf(constraintDistance)) {
+                failedConstraint = constraint.name();
+                return true;
+            }
+
+            return false;
+        }
+
         double constraintDistance = fitnessDistance(constraint);
         if (std::isinf(constraintDistance)) {
             failedConstraint = constraint.name();

Modified: trunk/Source/WebCore/platform/mediastream/RealtimeMediaSourceSupportedConstraints.cpp (216544 => 216545)


--- trunk/Source/WebCore/platform/mediastream/RealtimeMediaSourceSupportedConstraints.cpp	2017-05-09 21:52:53 UTC (rev 216544)
+++ trunk/Source/WebCore/platform/mediastream/RealtimeMediaSourceSupportedConstraints.cpp	2017-05-09 22:06:13 UTC (rev 216545)
@@ -35,72 +35,6 @@
 
 namespace WebCore {
 
-const AtomicString& RealtimeMediaSourceSupportedConstraints::nameForConstraint(MediaConstraintType constraint)
-{
-    static NeverDestroyed<AtomicString> unknownConstraintName(emptyString());
-    static NeverDestroyed<AtomicString> widthConstraintName("width");
-    static NeverDestroyed<AtomicString> heightConstraintName("height");
-    static NeverDestroyed<AtomicString> aspectRatioConstraintName("aspectRatio");
-    static NeverDestroyed<AtomicString> frameRateConstraintName("frameRate");
-    static NeverDestroyed<AtomicString> facingModeConstraintName("facingMode");
-    static NeverDestroyed<AtomicString> volumeConstraintName("volume");
-    static NeverDestroyed<AtomicString> sampleRateConstraintName("sampleRate");
-    static NeverDestroyed<AtomicString> sampleSizeConstraintName("sampleSize");
-    static NeverDestroyed<AtomicString> echoCancellationConstraintName("echoCancellation");
-    static NeverDestroyed<AtomicString> deviceIdConstraintName("deviceId");
-    static NeverDestroyed<AtomicString> groupIdConstraintName("groupId");
-    switch (constraint) {
-    case MediaConstraintType::Unknown:
-        return unknownConstraintName;
-    case MediaConstraintType::Width:
-        return widthConstraintName;
-    case MediaConstraintType::Height:
-        return heightConstraintName;
-    case MediaConstraintType::AspectRatio:
-        return aspectRatioConstraintName;
-    case MediaConstraintType::FrameRate:
-        return frameRateConstraintName;
-    case MediaConstraintType::FacingMode:
-        return facingModeConstraintName;
-    case MediaConstraintType::Volume:
-        return volumeConstraintName;
-    case MediaConstraintType::SampleRate:
-        return sampleRateConstraintName;
-    case MediaConstraintType::SampleSize:
-        return sampleSizeConstraintName;
-    case MediaConstraintType::EchoCancellation:
-        return echoCancellationConstraintName;
-    case MediaConstraintType::DeviceId:
-        return deviceIdConstraintName;
-    case MediaConstraintType::GroupId:
-        return groupIdConstraintName;
-    }
-
-    ASSERT_NOT_REACHED();
-    return emptyAtom;
-}
-
-MediaConstraintType RealtimeMediaSourceSupportedConstraints::constraintFromName(const String& constraintName)
-{
-    static NeverDestroyed<HashMap<AtomicString, MediaConstraintType>> nameToConstraintMap;
-    HashMap<AtomicString, MediaConstraintType>& nameToConstraintMapValue = nameToConstraintMap.get();
-    if (!nameToConstraintMapValue.size()) {
-        nameToConstraintMapValue.add("width", MediaConstraintType::Width);
-        nameToConstraintMapValue.add("height", MediaConstraintType::Height);
-        nameToConstraintMapValue.add("aspectRatio", MediaConstraintType::AspectRatio);
-        nameToConstraintMapValue.add("frameRate", MediaConstraintType::FrameRate);
-        nameToConstraintMapValue.add("facingMode", MediaConstraintType::FacingMode);
-        nameToConstraintMapValue.add("volume", MediaConstraintType::Volume);
-        nameToConstraintMapValue.add("sampleRate", MediaConstraintType::SampleRate);
-        nameToConstraintMapValue.add("sampleSize", MediaConstraintType::SampleSize);
-        nameToConstraintMapValue.add("echoCancellation", MediaConstraintType::EchoCancellation);
-        nameToConstraintMapValue.add("deviceId", MediaConstraintType::DeviceId);
-        nameToConstraintMapValue.add("groupId", MediaConstraintType::GroupId);
-    }
-    auto iter = nameToConstraintMapValue.find(constraintName);
-    return iter == nameToConstraintMapValue.end() ? MediaConstraintType::Unknown : iter->value;
-}
-
 bool RealtimeMediaSourceSupportedConstraints::supportsConstraint(MediaConstraintType constraint) const
 {
     switch (constraint) {

Modified: trunk/Source/WebCore/platform/mediastream/RealtimeMediaSourceSupportedConstraints.h (216544 => 216545)


--- trunk/Source/WebCore/platform/mediastream/RealtimeMediaSourceSupportedConstraints.h	2017-05-09 21:52:53 UTC (rev 216544)
+++ trunk/Source/WebCore/platform/mediastream/RealtimeMediaSourceSupportedConstraints.h	2017-05-09 22:06:13 UTC (rev 216545)
@@ -93,9 +93,6 @@
 
     bool supportsConstraint(MediaConstraintType) const;
 
-    static const AtomicString& nameForConstraint(MediaConstraintType);
-    static MediaConstraintType constraintFromName(const String&);
-
     template<class Encoder> void encode(Encoder&) const;
     template<class Decoder> static bool decode(Decoder&, RealtimeMediaSourceSupportedConstraints&);
 

Modified: trunk/Source/WebCore/platform/mediastream/mac/AVVideoCaptureSource.mm (216544 => 216545)


--- trunk/Source/WebCore/platform/mediastream/mac/AVVideoCaptureSource.mm	2017-05-09 21:52:53 UTC (rev 216544)
+++ trunk/Source/WebCore/platform/mediastream/mac/AVVideoCaptureSource.mm	2017-05-09 22:06:13 UTC (rev 216545)
@@ -116,7 +116,7 @@
         AVCaptureDeviceTypedef *device = [getAVCaptureDeviceClass() deviceWithUniqueID:deviceID];
         if (!device)
             return { };
-        return AVVideoCaptureSource::create(device, emptyString(), constraints);
+        return AVVideoCaptureSource::create(device, deviceID, constraints);
     }
 
 #if PLATFORM(IOS)

Modified: trunk/Source/WebCore/platform/mediastream/mac/RealtimeMediaSourceCenterMac.cpp (216544 => 216545)


--- trunk/Source/WebCore/platform/mediastream/mac/RealtimeMediaSourceCenterMac.cpp	2017-05-09 21:52:53 UTC (rev 216544)
+++ trunk/Source/WebCore/platform/mediastream/mac/RealtimeMediaSourceCenterMac.cpp	2017-05-09 22:06:13 UTC (rev 216545)
@@ -191,6 +191,7 @@
     for (auto& device : bestSources)
         sourceUIDs.uncheckedAppend(device->persistentID());
 
+    invalidConstraint = emptyString();
     return sourceUIDs;
 }
 

Modified: trunk/Source/WebKit2/ChangeLog (216544 => 216545)


--- trunk/Source/WebKit2/ChangeLog	2017-05-09 21:52:53 UTC (rev 216544)
+++ trunk/Source/WebKit2/ChangeLog	2017-05-09 22:06:13 UTC (rev 216545)
@@ -1,3 +1,55 @@
+2017-05-09  Eric Carlson  <eric.carl...@apple.com>
+
+        [MediaStream] deviceId constraint doesn't work with getUserMedia
+        https://bugs.webkit.org/show_bug.cgi?id=171877
+        <rdar://problem/31899730>
+
+        Reviewed by Jer Noble.
+
+        * Shared/WebCoreArgumentCoders.cpp:
+        (IPC::ArgumentCoder<MediaConstraintsData>::encode): Encode deviceIDHashSalt.
+        (IPC::ArgumentCoder<MediaConstraintsData>::decode): Decode deviceIDHashSalt.
+
+        * UIProcess/UserMediaPermissionCheckProxy.cpp:
+        (WebKit::UserMediaPermissionCheckProxy::UserMediaPermissionCheckProxy): Initialize
+        completion handler, frame ID, and security origins.
+        (WebKit::UserMediaPermissionCheckProxy::setUserMediaAccessInfo): Complete by calling
+        completion handler because we now sometimes request access info before calling gUM.
+        (WebKit::UserMediaPermissionCheckProxy::invalidate): Clear completion handler.
+        * UIProcess/UserMediaPermissionCheckProxy.h:
+
+        * UIProcess/UserMediaPermissionRequestManagerProxy.cpp:
+        (WebKit::FrameAuthorizationState::FrameAuthorizationState): Take security origins, not
+        UserMediaPermissionRequestProxy, so it can be constructed with a UserMediaPermissionCheckProxy.
+        (WebKit::FrameAuthorizationState::ensureSecurityOriginsAreEqual): Ditto. Clear has salt
+        when origins don't match.
+        (WebKit::UserMediaPermissionRequestManagerProxy::stateForRequest): Templatize.
+        (WebKit::UserMediaPermissionRequestManagerProxy::userMediaAccessWasDenied): Fix typo.
+        (WebKit::UserMediaPermissionRequestManagerProxy::userMediaAccessWasGranted): Ditto.
+        Don't set state for empty UIDs. Pass hash salt to web process.
+        (WebKit::UserMediaPermissionRequestManagerProxy::requestUserMediaPermissionForFrame):
+        The device ID hash salt is now required to validate constraints, so get it first.
+        (WebKit::UserMediaPermissionRequestManagerProxy::getUserMediaPermissionInfo): Helper
+        method used to get the device ID hash salt.
+        (WebKit::UserMediaPermissionRequestManagerProxy::enumerateMediaDevicesForFrame): Restructure
+        to use getUserMediaPermissionInfo.
+        (WebKit::UserMediaPermissionRequestManagerProxy::didCompleteUserMediaPermissionCheck): Deleted.
+        * UIProcess/UserMediaPermissionRequestManagerProxy.h:
+
+        * WebProcess/MediaStream/UserMediaPermissionRequestManager.cpp:
+        (WebKit::UserMediaPermissionRequestManager::userMediaAccessWasGranted): Add device ID
+        hash salt parameter.
+        * WebProcess/MediaStream/UserMediaPermissionRequestManager.h:
+
+        * WebProcess/WebPage/WebPage.cpp:
+        (WebKit::WebPage::userMediaAccessWasGranted): Ditto.
+        * WebProcess/WebPage/WebPage.h:
+        * WebProcess/WebPage/WebPage.messages.in:
+
+        * WebProcess/cocoa/UserMediaCaptureManager.cpp:
+        (WebKit::UserMediaCaptureManager::createCaptureSource): Use new MediaConstraintsData 
+        constructor.
+
 2017-05-10  Dean Jackson  <d...@apple.com>
 
         Restrict SVG filters to accessible security origins

Modified: trunk/Source/WebKit2/Shared/WebCoreArgumentCoders.cpp (216544 => 216545)


--- trunk/Source/WebKit2/Shared/WebCoreArgumentCoders.cpp	2017-05-09 21:52:53 UTC (rev 216544)
+++ trunk/Source/WebKit2/Shared/WebCoreArgumentCoders.cpp	2017-05-09 22:06:13 UTC (rev 216545)
@@ -2393,6 +2393,7 @@
 {
     encoder << constraint.mandatoryConstraints
         << constraint.advancedConstraints
+        << constraint.deviceIDHashSalt
         << constraint.isValid;
 }
 
@@ -2400,6 +2401,7 @@
 {
     return decoder.decode(constraints.mandatoryConstraints)
         && decoder.decode(constraints.advancedConstraints)
+        && decoder.decode(constraints.deviceIDHashSalt)
         && decoder.decode(constraints.isValid);
 }
 

Modified: trunk/Source/WebKit2/UIProcess/UserMediaPermissionCheckProxy.cpp (216544 => 216545)


--- trunk/Source/WebKit2/UIProcess/UserMediaPermissionCheckProxy.cpp	2017-05-09 21:52:53 UTC (rev 216544)
+++ trunk/Source/WebKit2/UIProcess/UserMediaPermissionCheckProxy.cpp	2017-05-09 22:06:13 UTC (rev 216545)
@@ -27,28 +27,34 @@
 #include "UserMediaPermissionCheckProxy.h"
 
 #include "UserMediaPermissionRequestManagerProxy.h"
+#include <WebCore/SecurityOrigin.h>
+#include <WebCore/SecurityOriginData.h>
 
+using namespace WebCore;
+
 namespace WebKit {
 
-UserMediaPermissionCheckProxy::UserMediaPermissionCheckProxy(UserMediaPermissionRequestManagerProxy& manager, uint64_t userMediaID)
-    : m_manager(&manager)
-    , m_userMediaID(userMediaID)
+UserMediaPermissionCheckProxy::UserMediaPermissionCheckProxy(uint64_t userMediaID, uint64_t frameID, CompletionHandler&& handler, const String& userMediaDocumentOriginIdentifier, const String& topLevelDocumentOriginIdentifier)
+    : m_userMediaID(userMediaID)
+    , m_frameID(frameID)
+    , m_completionHandler(WTFMove(handler))
+    , m_userMediaDocumentSecurityOrigin((SecurityOriginData::fromDatabaseIdentifier(userMediaDocumentOriginIdentifier)->securityOrigin()))
+    , m_topLevelDocumentSecurityOrigin(SecurityOriginData::fromDatabaseIdentifier(topLevelDocumentOriginIdentifier)->securityOrigin())
 {
 }
 
 void UserMediaPermissionCheckProxy::setUserMediaAccessInfo(const String& mediaDeviceIdentifierHashSalt, bool allowed)
 {
-    ASSERT(m_manager);
-    if (!m_manager)
+    if (!m_completionHandler)
         return;
 
-    m_manager->didCompleteUserMediaPermissionCheck(m_userMediaID, mediaDeviceIdentifierHashSalt, allowed);
-    m_manager = nullptr;
+    m_completionHandler(m_userMediaID, mediaDeviceIdentifierHashSalt, allowed);
+    m_completionHandler = nullptr;
 }
 
 void UserMediaPermissionCheckProxy::invalidate()
 {
-    m_manager = nullptr;
+    m_completionHandler = nullptr;
 }
 
 } // namespace WebKit

Modified: trunk/Source/WebKit2/UIProcess/UserMediaPermissionCheckProxy.h (216544 => 216545)


--- trunk/Source/WebKit2/UIProcess/UserMediaPermissionCheckProxy.h	2017-05-09 21:52:53 UTC (rev 216544)
+++ trunk/Source/WebKit2/UIProcess/UserMediaPermissionCheckProxy.h	2017-05-09 22:06:13 UTC (rev 216545)
@@ -29,6 +29,10 @@
 #include "APIObject.h"
 #include <wtf/text/WTFString.h>
 
+namespace WebCore {
+class SecurityOrigin;
+}
+
 namespace WebKit {
 
 class UserMediaPermissionRequestManagerProxy;
@@ -35,19 +39,29 @@
 
 class UserMediaPermissionCheckProxy : public API::ObjectImpl<API::Object::Type::UserMediaPermissionCheck> {
 public:
-    static Ref<UserMediaPermissionCheckProxy> create(UserMediaPermissionRequestManagerProxy& manager, uint64_t userMediaID)
+
+    using CompletionHandler = std::function<void(uint64_t, const String&, bool allowed)>;
+
+    static Ref<UserMediaPermissionCheckProxy> create(uint64_t userMediaID, uint64_t frameID, CompletionHandler&& handler, const String& userMediaDocumentOriginIdentifier, const String& topLevelDocumentOriginIdentifier)
     {
-        return adoptRef(*new UserMediaPermissionCheckProxy(manager, userMediaID));
+        return adoptRef(*new UserMediaPermissionCheckProxy(userMediaID, frameID, WTFMove(handler), userMediaDocumentOriginIdentifier, topLevelDocumentOriginIdentifier));
     }
 
     void setUserMediaAccessInfo(const String&, bool allowed);
     void invalidate();
 
+    uint64_t frameID() const { return m_frameID; }
+    WebCore::SecurityOrigin* userMediaDocumentSecurityOrigin() { return &m_userMediaDocumentSecurityOrigin.get(); }
+    WebCore::SecurityOrigin* topLevelDocumentSecurityOrigin() { return &m_topLevelDocumentSecurityOrigin.get(); }
+
 private:
-    UserMediaPermissionCheckProxy(UserMediaPermissionRequestManagerProxy&, uint64_t);
+    UserMediaPermissionCheckProxy(uint64_t userMediaID, uint64_t frameID, CompletionHandler&&, const String& userMediaDocumentOriginIdentifier, const String& topLevelDocumentOriginIdentifier);
 
-    UserMediaPermissionRequestManagerProxy* m_manager;
     uint64_t m_userMediaID;
+    uint64_t m_frameID;
+    CompletionHandler m_completionHandler;
+    Ref<WebCore::SecurityOrigin> m_userMediaDocumentSecurityOrigin;
+    Ref<WebCore::SecurityOrigin> m_topLevelDocumentSecurityOrigin;
 };
 
 } // namespace WebKit

Modified: trunk/Source/WebKit2/UIProcess/UserMediaPermissionRequestManagerProxy.cpp (216544 => 216545)


--- trunk/Source/WebKit2/UIProcess/UserMediaPermissionRequestManagerProxy.cpp	2017-05-09 21:52:53 UTC (rev 216544)
+++ trunk/Source/WebKit2/UIProcess/UserMediaPermissionRequestManagerProxy.cpp	2017-05-09 22:06:13 UTC (rev 216545)
@@ -39,9 +39,9 @@
 
 namespace WebKit {
 
-FrameAuthorizationState::FrameAuthorizationState(UserMediaPermissionRequestProxy& request)
-    : m_userMediaDocumentSecurityOrigin(request.userMediaDocumentSecurityOrigin())
-    , m_topLevelDocumentSecurityOrigin(request.topLevelDocumentSecurityOrigin())
+FrameAuthorizationState::FrameAuthorizationState(SecurityOrigin* userMediaDocumentSecurityOrigin, SecurityOrigin* topLevelDocumentSecurityOrigin)
+    : m_userMediaDocumentSecurityOrigin(userMediaDocumentSecurityOrigin)
+    , m_topLevelDocumentSecurityOrigin(topLevelDocumentSecurityOrigin)
 {
 }
 
@@ -65,32 +65,34 @@
         m_authorizedDeviceUIDs.remove(index);
 }
 
-void FrameAuthorizationState::ensureSecurityOriginsAreEqual(UserMediaPermissionRequestProxy& request)
+void FrameAuthorizationState::ensureSecurityOriginsAreEqual(WebCore::SecurityOrigin* userMediaDocumentSecurityOrigin, WebCore::SecurityOrigin* topLevelDocumentSecurityOrigin)
 {
     do {
-        if (!m_userMediaDocumentSecurityOrigin || !m_userMediaDocumentSecurityOrigin->equal(request.userMediaDocumentSecurityOrigin()))
+        if (!m_userMediaDocumentSecurityOrigin || !m_userMediaDocumentSecurityOrigin->equal(userMediaDocumentSecurityOrigin))
             break;
 
-        if (!m_topLevelDocumentSecurityOrigin || !m_topLevelDocumentSecurityOrigin->equal(request.topLevelDocumentSecurityOrigin()))
+        if (!m_topLevelDocumentSecurityOrigin || !m_topLevelDocumentSecurityOrigin->equal(topLevelDocumentSecurityOrigin))
             break;
 
         return;
     } while (0);
 
-    m_userMediaDocumentSecurityOrigin = request.userMediaDocumentSecurityOrigin();
-    m_topLevelDocumentSecurityOrigin = request.topLevelDocumentSecurityOrigin();
+    m_userMediaDocumentSecurityOrigin = userMediaDocumentSecurityOrigin;
+    m_topLevelDocumentSecurityOrigin = topLevelDocumentSecurityOrigin;
     m_authorizedDeviceUIDs.clear();
+    m_deviceIdentifierHashSalt = emptyString();
 }
 
-FrameAuthorizationState& UserMediaPermissionRequestManagerProxy::stateForRequest(UserMediaPermissionRequestProxy& request)
+template <typename RequestType>
+FrameAuthorizationState& UserMediaPermissionRequestManagerProxy::stateForRequest(RequestType& request)
 {
     auto& state = m_frameStates.add(request.frameID(), nullptr).iterator->value;
     if (state) {
-        state->ensureSecurityOriginsAreEqual(request);
+        state->ensureSecurityOriginsAreEqual(request.userMediaDocumentSecurityOrigin(), request.topLevelDocumentSecurityOrigin());
         return *state;
     }
 
-    state = std::make_unique<FrameAuthorizationState>(request);
+    state = std::make_unique<FrameAuthorizationState>(request.userMediaDocumentSecurityOrigin(), request.topLevelDocumentSecurityOrigin());
     return *state;
 }
 
@@ -183,11 +185,11 @@
     if (!request)
         return;
 
-    auto fameState = stateForRequest(*request);
+    auto frameState = stateForRequest(*request);
     for (const auto& deviceUID : request->videoDeviceUIDs())
-        fameState.setHasPermissionToUseCaptureDevice(deviceUID, false);
+        frameState.setHasPermissionToUseCaptureDevice(deviceUID, false);
     for (const auto& deviceUID : request->audioDeviceUIDs())
-        fameState.setHasPermissionToUseCaptureDevice(deviceUID, false);
+        frameState.setHasPermissionToUseCaptureDevice(deviceUID, false);
 
     denyRequest(userMediaID, reason, emptyString());
 }
@@ -216,13 +218,15 @@
     if (!request)
         return;
 
-    auto& fameState = stateForRequest(*request);
-    fameState.setHasPermissionToUseCaptureDevice(audioDeviceUID, true);
-    fameState.setHasPermissionToUseCaptureDevice(videoDeviceUID, true);
+    auto& frameState = stateForRequest(*request);
+    if (!audioDeviceUID.isEmpty())
+        frameState.setHasPermissionToUseCaptureDevice(audioDeviceUID, true);
+    if (!videoDeviceUID.isEmpty())
+        frameState.setHasPermissionToUseCaptureDevice(videoDeviceUID, true);
 
     UserMediaProcessManager::singleton().willCreateMediaStream(*this, !audioDeviceUID.isEmpty(), !videoDeviceUID.isEmpty());
 
-    m_page.process().send(Messages::WebPage::UserMediaAccessWasGranted(userMediaID, audioDeviceUID, videoDeviceUID), m_page.pageID());
+    m_page.process().send(Messages::WebPage::UserMediaAccessWasGranted(userMediaID, audioDeviceUID, videoDeviceUID, frameState.deviceIdentifierHashSalt()), m_page.pageID());
 #else
     UNUSED_PARAM(userMediaID);
     UNUSED_PARAM(audioDeviceUID);
@@ -266,21 +270,21 @@
             return;
         }
 
-        auto userMediaOrigin = API::SecurityOrigin::create(SecurityOriginData::fromDatabaseIdentifier(userMediaDocumentOriginIdentifier)->securityOrigin());
-        auto topLevelOrigin = API::SecurityOrigin::create(SecurityOriginData::fromDatabaseIdentifier(topLevelDocumentOriginIdentifier)->securityOrigin());
+        bool authorizedForAudio = false;
+        bool authorizedForVideo = false;
+        auto userMediaOrigin = API::SecurityOrigin::create(SecurityOriginData::fromDatabaseIdentifier(userMediaDocumentOriginIdentifier).value_or(SecurityOriginData()).securityOrigin());
+        auto topLevelOrigin = API::SecurityOrigin::create(SecurityOriginData::fromDatabaseIdentifier(topLevelDocumentOriginIdentifier).value_or(SecurityOriginData()).securityOrigin());
         auto request = createRequest(userMediaID, frameID, userMediaDocumentOriginIdentifier, topLevelDocumentOriginIdentifier, audioDeviceUIDs, videoDeviceUIDs);
 
-        bool authorizedForAudio = false;
-        bool authorizedForVideo = false;
-        auto& fameState = stateForRequest(request);
+        auto& frameState = stateForRequest(request.get());
         for (auto deviceUID : audioDeviceUIDs) {
-            if (fameState.hasPermissionToUseCaptureDevice(deviceUID)) {
+            if (frameState.hasPermissionToUseCaptureDevice(deviceUID)) {
                 authorizedForAudio = true;
                 break;
             }
         }
         for (auto deviceUID : videoDeviceUIDs) {
-            if (fameState.hasPermissionToUseCaptureDevice(deviceUID)) {
+            if (frameState.hasPermissionToUseCaptureDevice(deviceUID)) {
                 authorizedForVideo = true;
                 break;
             }
@@ -302,11 +306,37 @@
         return;
     }
 
-    auto audioConstraints = MediaConstraintsImpl::create(MediaConstraintsData(audioConstraintsData));
-    auto videoConstraints = MediaConstraintsImpl::create(MediaConstraintsData(videoConstraintsData));
+    auto validateConstraintsHandler = [this, userMediaID, validHandler, invalidHandler, audioConstraintsData, videoConstraintsData](const String& deviceIdentifierHashSalt) {
+        syncWithWebCorePrefs();
 
-    syncWithWebCorePrefs();
-    RealtimeMediaSourceCenter::singleton().validateRequestConstraints(validHandler, invalidHandler, audioConstraints, videoConstraints);
+        auto audioConstraints = MediaConstraintsImpl::create({audioConstraintsData, deviceIdentifierHashSalt});
+        auto videoConstraints = MediaConstraintsImpl::create({videoConstraintsData, deviceIdentifierHashSalt});
+
+        RealtimeMediaSourceCenter::singleton().validateRequestConstraints(validHandler, invalidHandler, audioConstraints, videoConstraints);
+    };
+
+    auto haveDeviceSaltHandler = [this, userMediaID, frameID, validateConstraintsHandler](uint64_t userMediaID, const String& deviceIdentifierHashSalt, bool originHasPersistentAccess) {
+
+        auto request = m_pendingDeviceRequests.take(userMediaID);
+        if (!request)
+            return;
+
+        if (!m_page.isValid())
+            return;
+
+        auto& frameState = stateForRequest(*request);
+        frameState.setDeviceIdentifierHashSalt(deviceIdentifierHashSalt);
+        frameState.setHasPersistentAccess(originHasPersistentAccess);
+        validateConstraintsHandler(deviceIdentifierHashSalt);
+    };
+
+    auto frameState =  m_frameStates.get(frameID);
+    if (frameState && !frameState->deviceIdentifierHashSalt().isEmpty()) {
+        validateConstraintsHandler(frameState->deviceIdentifierHashSalt());
+        return;
+    }
+
+    getUserMediaPermissionInfo(userMediaID, frameID, WTFMove(haveDeviceSaltHandler), WTFMove(userMediaDocumentOriginIdentifier), WTFMove(topLevelDocumentOriginIdentifier));
 #else
     UNUSED_PARAM(userMediaID);
     UNUSED_PARAM(frameID);
@@ -317,42 +347,57 @@
 #endif
 }
 
-void UserMediaPermissionRequestManagerProxy::enumerateMediaDevicesForFrame(uint64_t userMediaID, uint64_t frameID, String userMediaDocumentOriginIdentifier, String topLevelDocumentOriginIdentifier)
+#if ENABLE(MEDIA_STREAM)
+void UserMediaPermissionRequestManagerProxy::getUserMediaPermissionInfo(uint64_t userMediaID, uint64_t frameID, UserMediaPermissionCheckProxy::CompletionHandler&& handler, const String&& userMediaDocumentOriginIdentifier, const String&& topLevelDocumentOriginIdentifier)
 {
-#if ENABLE(MEDIA_STREAM)
-    auto request = UserMediaPermissionCheckProxy::create(*this, userMediaID);
+    auto request = UserMediaPermissionCheckProxy::create(userMediaID, frameID, WTFMove(handler), userMediaDocumentOriginIdentifier, topLevelDocumentOriginIdentifier);
+
     m_pendingDeviceRequests.add(userMediaID, request.ptr());
 
+    auto frameState =  m_frameStates.get(frameID);
+    if (frameState && !frameState->deviceIdentifierHashSalt().isEmpty()) {
+        handler(userMediaID, frameState->deviceIdentifierHashSalt(), frameState->hasPersistentAccess());
+        return;
+    }
+
     auto userMediaOrigin = API::SecurityOrigin::create(SecurityOriginData::fromDatabaseIdentifier(userMediaDocumentOriginIdentifier).value_or(SecurityOriginData()).securityOrigin());
     auto topLevelOrigin = API::SecurityOrigin::create(SecurityOriginData::fromDatabaseIdentifier(topLevelDocumentOriginIdentifier).value_or(SecurityOriginData()).securityOrigin());
-
     if (!m_page.uiClient().checkUserMediaPermissionForOrigin(m_page, *m_page.process().webFrame(frameID), *userMediaOrigin.get(), *topLevelOrigin.get(), request.get())) {
         m_pendingDeviceRequests.take(userMediaID);
-        m_page.process().send(Messages::WebPage::DidCompleteMediaDeviceEnumeration(userMediaID, Vector<WebCore::CaptureDevice>(), emptyString(), false), m_page.pageID());
+
+        handler(userMediaID, emptyString(), false);
     }
-#else
-    UNUSED_PARAM(userMediaID);
-    UNUSED_PARAM(frameID);
-    UNUSED_PARAM(userMediaDocumentOriginIdentifier);
-    UNUSED_PARAM(topLevelDocumentOriginIdentifier);
+}
 #endif
-}
 
-void UserMediaPermissionRequestManagerProxy::didCompleteUserMediaPermissionCheck(uint64_t userMediaID, const String& deviceIdentifierHashSalt, bool originHasPersistentAccess)
+void UserMediaPermissionRequestManagerProxy::enumerateMediaDevicesForFrame(uint64_t userMediaID, uint64_t frameID, String userMediaDocumentOriginIdentifier, String topLevelDocumentOriginIdentifier)
 {
-    if (!m_page.isValid())
-        return;
+#if ENABLE(MEDIA_STREAM)
 
-    if (!m_pendingDeviceRequests.take(userMediaID))
-        return;
+    auto completionHandler = [this, userMediaID](uint64_t userMediaID, const String& deviceIdentifierHashSalt, bool originHasPersistentAccess) {
+        auto request = m_pendingDeviceRequests.take(userMediaID);
+        if (!request)
+            return;
 
-#if ENABLE(MEDIA_STREAM)
-    syncWithWebCorePrefs();
-    auto deviceInfo = RealtimeMediaSourceCenter::singleton().getMediaStreamDevices();
-    m_page.process().send(Messages::WebPage::DidCompleteMediaDeviceEnumeration(userMediaID, deviceInfo, deviceIdentifierHashSalt, originHasPersistentAccess), m_page.pageID());
+        if (!m_page.isValid())
+            return;
+
+        auto& frameState = stateForRequest(*request);
+        ASSERT(frameState.deviceIdentifierHashSalt().isEmpty() || frameState.deviceIdentifierHashSalt() == deviceIdentifierHashSalt);
+        frameState.setDeviceIdentifierHashSalt(deviceIdentifierHashSalt);
+        frameState.setHasPersistentAccess(originHasPersistentAccess);
+
+        syncWithWebCorePrefs();
+        auto deviceInfo = RealtimeMediaSourceCenter::singleton().getMediaStreamDevices();
+        m_page.process().send(Messages::WebPage::DidCompleteMediaDeviceEnumeration(userMediaID, deviceInfo, deviceIdentifierHashSalt, originHasPersistentAccess), m_page.pageID());
+    };
+
+    getUserMediaPermissionInfo(userMediaID, frameID, WTFMove(completionHandler), WTFMove(userMediaDocumentOriginIdentifier), WTFMove(topLevelDocumentOriginIdentifier));
 #else
-    UNUSED_PARAM(deviceIdentifierHashSalt);
-    UNUSED_PARAM(originHasPersistentAccess);
+    UNUSED_PARAM(userMediaID);
+    UNUSED_PARAM(frameID);
+    UNUSED_PARAM(userMediaDocumentOriginIdentifier);
+    UNUSED_PARAM(topLevelDocumentOriginIdentifier);
 #endif
 }
 

Modified: trunk/Source/WebKit2/UIProcess/UserMediaPermissionRequestManagerProxy.h (216544 => 216545)


--- trunk/Source/WebKit2/UIProcess/UserMediaPermissionRequestManagerProxy.h	2017-05-09 21:52:53 UTC (rev 216544)
+++ trunk/Source/WebKit2/UIProcess/UserMediaPermissionRequestManagerProxy.h	2017-05-09 22:06:13 UTC (rev 216545)
@@ -30,6 +30,7 @@
 namespace WebCore {
 class CaptureDevice;
 struct MediaConstraintsData;
+class SecurityOrigin;
 };
 
 namespace WebKit {
@@ -38,17 +39,25 @@
 
 class FrameAuthorizationState {
 public:
-    explicit FrameAuthorizationState(UserMediaPermissionRequestProxy&);
+    explicit FrameAuthorizationState(WebCore::SecurityOrigin* userMediaDocumentSecurityOrigin, WebCore::SecurityOrigin* topLevelDocumentSecurityOrigin);
 
     bool hasPermissionToUseCaptureDevice(const String& deviceUID);
     void setHasPermissionToUseCaptureDevice(const String&, bool);
 
-    void ensureSecurityOriginsAreEqual(UserMediaPermissionRequestProxy&);
+    void ensureSecurityOriginsAreEqual(WebCore::SecurityOrigin* userMediaDocumentSecurityOrigin, WebCore::SecurityOrigin* topLevelDocumentSecurityOrigin);
 
+    void setDeviceIdentifierHashSalt(const String& hashSalt) { m_deviceIdentifierHashSalt = hashSalt; }
+    String deviceIdentifierHashSalt() const { return m_deviceIdentifierHashSalt; }
+
+    bool hasPersistentAccess() const { return m_hasPersistentAccess; }
+    void setHasPersistentAccess(bool value) { m_hasPersistentAccess = value; }
+
 private:
     RefPtr<WebCore::SecurityOrigin> m_userMediaDocumentSecurityOrigin;
     RefPtr<WebCore::SecurityOrigin> m_topLevelDocumentSecurityOrigin;
     Vector<String> m_authorizedDeviceUIDs;
+    String m_deviceIdentifierHashSalt;
+    bool m_hasPersistentAccess { false };
 };
 
 class UserMediaPermissionRequestManagerProxy {
@@ -64,12 +73,12 @@
 
     void userMediaAccessWasGranted(uint64_t, const String& audioDeviceUID, const String& videoDeviceUID);
     void userMediaAccessWasDenied(uint64_t, UserMediaPermissionRequestProxy::UserMediaAccessDenialReason);
-    FrameAuthorizationState& stateForRequest(UserMediaPermissionRequestProxy&);
 
+    template <typename RequestType>
+    FrameAuthorizationState& stateForRequest(RequestType&);
+
     void enumerateMediaDevicesForFrame(uint64_t userMediaID, uint64_t frameID, String userMediaDocumentOriginIdentifier, String topLevelDocumentOriginIdentifier);
 
-    void didCompleteUserMediaPermissionCheck(uint64_t, const String&, bool allow);
-
     void stopCapture();
     void scheduleNextRejection();
     void rejectionTimerFired();
@@ -81,7 +90,9 @@
 private:
     Ref<UserMediaPermissionRequestProxy> createRequest(uint64_t userMediaID, uint64_t frameID, const String&userMediaDocumentOriginIdentifier, const String& topLevelDocumentOriginIdentifier, const Vector<String>& audioDeviceUIDs, const Vector<String>& videoDeviceUIDs);
     void denyRequest(uint64_t userMediaID, UserMediaPermissionRequestProxy::UserMediaAccessDenialReason, const String& invalidConstraint);
-    Ref<UserMediaPermissionCheckProxy> createUserMediaPermissionCheck(uint64_t userMediaID);
+
+    void getUserMediaPermissionInfo(uint64_t userMediaID, uint64_t frameID, UserMediaPermissionCheckProxy::CompletionHandler&&, const String&&userMediaDocumentOriginIdentifier, const String&& topLevelDocumentOriginIdentifier);
+
     void syncWithWebCorePrefs() const;
 
     HashMap<uint64_t, RefPtr<UserMediaPermissionRequestProxy>> m_pendingUserMediaRequests;

Modified: trunk/Source/WebKit2/WebProcess/MediaStream/UserMediaPermissionRequestManager.cpp (216544 => 216545)


--- trunk/Source/WebKit2/WebProcess/MediaStream/UserMediaPermissionRequestManager.cpp	2017-05-09 21:52:53 UTC (rev 216544)
+++ trunk/Source/WebKit2/WebProcess/MediaStream/UserMediaPermissionRequestManager.cpp	2017-05-09 22:06:13 UTC (rev 216545)
@@ -154,7 +154,7 @@
     m_userMediaRequestToIDMap.remove(&request);
 }
 
-void UserMediaPermissionRequestManager::userMediaAccessWasGranted(uint64_t requestID, const String& audioDeviceUID, const String& videoDeviceUID)
+void UserMediaPermissionRequestManager::userMediaAccessWasGranted(uint64_t requestID, const String& audioDeviceUID, const String& videoDeviceUID, const String& deviceIdentifierHashSalt)
 {
     auto request = m_idToUserMediaRequestMap.take(requestID);
     if (!request)
@@ -161,7 +161,7 @@
         return;
     removeMediaRequestFromMaps(*request);
 
-    request->allow(audioDeviceUID, videoDeviceUID);
+    request->allow(audioDeviceUID, videoDeviceUID, deviceIdentifierHashSalt);
 }
 
 void UserMediaPermissionRequestManager::userMediaAccessWasDenied(uint64_t requestID, WebCore::UserMediaRequest::MediaAccessDenialReason reason, const String& invalidConstraint)

Modified: trunk/Source/WebKit2/WebProcess/MediaStream/UserMediaPermissionRequestManager.h (216544 => 216545)


--- trunk/Source/WebKit2/WebProcess/MediaStream/UserMediaPermissionRequestManager.h	2017-05-09 21:52:53 UTC (rev 216544)
+++ trunk/Source/WebKit2/WebProcess/MediaStream/UserMediaPermissionRequestManager.h	2017-05-09 22:06:13 UTC (rev 216545)
@@ -45,7 +45,7 @@
 
     void startUserMediaRequest(WebCore::UserMediaRequest&);
     void cancelUserMediaRequest(WebCore::UserMediaRequest&);
-    void userMediaAccessWasGranted(uint64_t, const String& audioDeviceUID, const String& videoDeviceUID);
+    void userMediaAccessWasGranted(uint64_t, const String& audioDeviceUID, const String& videoDeviceUID, const String& deviceIdentifierHashSalt);
     void userMediaAccessWasDenied(uint64_t, WebCore::UserMediaRequest::MediaAccessDenialReason, const String&);
 
     void enumerateMediaDevices(WebCore::MediaDevicesEnumerationRequest&);

Modified: trunk/Source/WebKit2/WebProcess/WebPage/WebPage.cpp (216544 => 216545)


--- trunk/Source/WebKit2/WebProcess/WebPage/WebPage.cpp	2017-05-09 21:52:53 UTC (rev 216544)
+++ trunk/Source/WebKit2/WebProcess/WebPage/WebPage.cpp	2017-05-09 22:06:13 UTC (rev 216545)
@@ -3864,9 +3864,9 @@
 }
 
 #if ENABLE(MEDIA_STREAM)
-void WebPage::userMediaAccessWasGranted(uint64_t userMediaID, const String& audioDeviceUID, const String& videoDeviceUID)
+void WebPage::userMediaAccessWasGranted(uint64_t userMediaID, const String& audioDeviceUID, const String& videoDeviceUID, const String& mediaDeviceIdentifierHashSalt)
 {
-    m_userMediaPermissionRequestManager->userMediaAccessWasGranted(userMediaID, audioDeviceUID, videoDeviceUID);
+    m_userMediaPermissionRequestManager->userMediaAccessWasGranted(userMediaID, audioDeviceUID, videoDeviceUID, mediaDeviceIdentifierHashSalt);
 }
 
 void WebPage::userMediaAccessWasDenied(uint64_t userMediaID, uint64_t reason, String invalidConstraint)

Modified: trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h (216544 => 216545)


--- trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h	2017-05-09 21:52:53 UTC (rev 216544)
+++ trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h	2017-05-09 22:06:13 UTC (rev 216545)
@@ -1174,7 +1174,7 @@
     void didReceiveNotificationPermissionDecision(uint64_t notificationID, bool allowed);
 
 #if ENABLE(MEDIA_STREAM)
-    void userMediaAccessWasGranted(uint64_t userMediaID, const String& audioDeviceUID, const String& videoDeviceUID);
+    void userMediaAccessWasGranted(uint64_t userMediaID, const String& audioDeviceUID, const String& videoDeviceUID, const String& mediaDeviceIdentifierHashSalt);
     void userMediaAccessWasDenied(uint64_t userMediaID, uint64_t reason, String invalidConstraint);
 
     void didCompleteMediaDeviceEnumeration(uint64_t userMediaID, const Vector<WebCore::CaptureDevice>& devices, const String& deviceIdentifierHashSalt, bool originHasPersistentAccess);

Modified: trunk/Source/WebKit2/WebProcess/WebPage/WebPage.messages.in (216544 => 216545)


--- trunk/Source/WebKit2/WebProcess/WebPage/WebPage.messages.in	2017-05-09 21:52:53 UTC (rev 216544)
+++ trunk/Source/WebKit2/WebProcess/WebPage/WebPage.messages.in	2017-05-09 22:06:13 UTC (rev 216545)
@@ -298,7 +298,7 @@
 
 #if ENABLE(MEDIA_STREAM)
     # MediaSteam
-    UserMediaAccessWasGranted(uint64_t userMediaID, String audioDeviceUID, String videoDeviceUID)
+    UserMediaAccessWasGranted(uint64_t userMediaID, String audioDeviceUID, String videoDeviceUID, String mediaDeviceIdentifierHashSalt)
     UserMediaAccessWasDenied(uint64_t userMediaID, uint64_t reason, String invalidConstraint)
     DidCompleteMediaDeviceEnumeration(uint64_t userMediaID, Vector<WebCore::CaptureDevice> devices, String mediaDeviceIdentifierHashSalt, bool hasPersistentAccess)
 #if ENABLE(SANDBOX_EXTENSIONS)

Modified: trunk/Source/WebKit2/WebProcess/cocoa/UserMediaCaptureManager.cpp (216544 => 216545)


--- trunk/Source/WebKit2/WebProcess/cocoa/UserMediaCaptureManager.cpp	2017-05-09 21:52:53 UTC (rev 216544)
+++ trunk/Source/WebKit2/WebProcess/cocoa/UserMediaCaptureManager.cpp	2017-05-09 22:06:13 UTC (rev 216545)
@@ -212,15 +212,11 @@
         return { };
 
     uint64_t id = nextSessionID();
-    MediaConstraintsData constraintsData;
-    constraintsData.mandatoryConstraints = constraints->mandatoryConstraints();
-    constraintsData.advancedConstraints = constraints->advancedConstraints();
-    constraintsData.isValid = constraints->isValid();
     bool succeeded;
 
     RealtimeMediaSourceSettings settings;
     String errorMessage;
-    if (!m_process.sendSync(Messages::UserMediaCaptureManagerProxy::CreateMediaSourceForCaptureDeviceWithConstraints(id, deviceID, sourceType, constraintsData), Messages::UserMediaCaptureManagerProxy::CreateMediaSourceForCaptureDeviceWithConstraints::Reply(succeeded, errorMessage, settings), 0))
+    if (!m_process.sendSync(Messages::UserMediaCaptureManagerProxy::CreateMediaSourceForCaptureDeviceWithConstraints(id, deviceID, sourceType, *constraints), Messages::UserMediaCaptureManagerProxy::CreateMediaSourceForCaptureDeviceWithConstraints::Reply(succeeded, errorMessage, settings), 0))
         return WTFMove(errorMessage);
 
     auto source = adoptRef(*new Source(String::number(id), sourceType, emptyString(), id, *this));
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to