Title: [241167] trunk
Revision
241167
Author
you...@apple.com
Date
2019-02-07 15:49:00 -0800 (Thu, 07 Feb 2019)

Log Message

Filter out Overconstrainederror.constraint when getUserMedia is not granted
https://bugs.webkit.org/show_bug.cgi?id=194240

Reviewed by Eric Carlson.

Source/WebKit:

Make sure in UIProcess to filter out constraint if either the page was not granted gum access or it has no persistent access.

Refactor UserMediaPermissionRequestManagerProxy to make the implementation easier to understand.

Covered by added test.

* UIProcess/UserMediaPermissionCheckProxy.cpp:
(WebKit::UserMediaPermissionCheckProxy::setUserMediaAccessInfo):
* UIProcess/UserMediaPermissionRequestManagerProxy.cpp:
(WebKit::UserMediaPermissionRequestManagerProxy::captureDevicesChanged):
(WebKit::UserMediaPermissionRequestManagerProxy::userMediaAccessWasGranted):
(WebKit::UserMediaPermissionRequestManagerProxy::grantAccess):
(WebKit::UserMediaPermissionRequestManagerProxy::getRequestAction):
(WebKit::UserMediaPermissionRequestManagerProxy::requestUserMediaPermissionForFrame):
(WebKit::UserMediaPermissionRequestManagerProxy::processUserMediaPermissionRequest):
(WebKit::UserMediaPermissionRequestManagerProxy::processUserMediaPermissionInvalidRequest):
(WebKit::UserMediaPermissionRequestManagerProxy::processUserMediaPermissionValidRequest):
(WebKit::UserMediaPermissionRequestManagerProxy::getUserMediaPermissionInfo):
(WebKit::UserMediaPermissionRequestManagerProxy::wasGrantedVideoOrAudioAccess):
(WebKit::UserMediaPermissionRequestManagerProxy::computeFilteredDeviceList):
(WebKit::UserMediaPermissionRequestManagerProxy::enumerateMediaDevicesForFrame):
(WebKit::UserMediaPermissionRequestManagerProxy::createPermissionRequest): Deleted.
* UIProcess/UserMediaPermissionRequestManagerProxy.h:
* UIProcess/UserMediaPermissionRequestProxy.h:
(WebKit::UserMediaPermissionRequestProxy::isPending const):
(WebKit::UserMediaPermissionRequestProxy::setEligibleVideoDeviceUIDs):
(WebKit::UserMediaPermissionRequestProxy::setEligibleAudioDeviceUIDs):
(WebKit::UserMediaPermissionRequestProxy::hasAudioDevice const):
(WebKit::UserMediaPermissionRequestProxy::hasVideoDevice const):
(WebKit::UserMediaPermissionRequestProxy::hasPersistentAccess const):
(WebKit::UserMediaPermissionRequestProxy::setHasPersistentAccess):
(WebKit::UserMediaPermissionRequestProxy::userMediaID const):
(WebKit::UserMediaPermissionRequestProxy::topLevelDocumentSecurityOrigin const):
(WebKit::UserMediaPermissionRequestProxy::userMediaDocumentSecurityOrigin const):
(WebKit::UserMediaPermissionRequestProxy::userRequest const):
(WebKit::UserMediaPermissionRequestProxy::setDeviceIdentifierHashSalt):
(WebKit::UserMediaPermissionRequestProxy::deviceIdentifierHashSalt const):
(WebKit::UserMediaPermissionRequestProxy::audioDevice const):
(WebKit::UserMediaPermissionRequestProxy::videoDevice const):
* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::requestUserMediaPermissionForFrame):
* UIProcess/WebPageProxy.h:

LayoutTests:

* fast/mediastream/overconstrainederror-constraint-expected.txt: Added.
* fast/mediastream/overconstrainederror-constraint.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (241166 => 241167)


--- trunk/LayoutTests/ChangeLog	2019-02-07 23:37:23 UTC (rev 241166)
+++ trunk/LayoutTests/ChangeLog	2019-02-07 23:49:00 UTC (rev 241167)
@@ -1,3 +1,13 @@
+2019-02-07  Youenn Fablet  <you...@apple.com>
+
+        Filter out Overconstrainederror.constraint when getUserMedia is not granted
+        https://bugs.webkit.org/show_bug.cgi?id=194240
+
+        Reviewed by Eric Carlson.
+
+        * fast/mediastream/overconstrainederror-constraint-expected.txt: Added.
+        * fast/mediastream/overconstrainederror-constraint.html: Added.
+
 2019-02-07  Timothy Hatcher  <timo...@apple.com>
 
         Overflow element scrollbar is light for dark mode content.

Added: trunk/LayoutTests/fast/mediastream/overconstrainederror-constraint-expected.txt (0 => 241167)


--- trunk/LayoutTests/fast/mediastream/overconstrainederror-constraint-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/mediastream/overconstrainederror-constraint-expected.txt	2019-02-07 23:49:00 UTC (rev 241167)
@@ -0,0 +1,4 @@
+
+PASS Before grant 
+PASS After grant 
+

Added: trunk/LayoutTests/fast/mediastream/overconstrainederror-constraint.html (0 => 241167)


--- trunk/LayoutTests/fast/mediastream/overconstrainederror-constraint.html	                        (rev 0)
+++ trunk/LayoutTests/fast/mediastream/overconstrainederror-constraint.html	2019-02-07 23:49:00 UTC (rev 241167)
@@ -0,0 +1,39 @@
+<!doctype html>
+<html>
+    <head>
+        <meta charset="utf-8">
+        <title>OverConstrainedError.constraint testing</title>
+        <script src=""
+        <script src=""
+    </head>
+    <body>
+
+        <script>
+if (window.testRunner)
+    testRunner.setUserMediaPermission(true);
+if (window.internals)
+    window.internals.setMockMediaCaptureDevicesEnabled(true);
+
+promise_test(async () => {
+    return navigator.mediaDevices.getUserMedia({audio: {deviceId: {exact:"none"}}}).then(
+        () => assert_not_reached("gum should fail"),
+        (e) => {
+            assert_true(e instanceof OverconstrainedError);
+            assert_equals(e.constraint, "", "constraint should be the empty string");
+        }
+    );
+}, "Before grant");
+
+promise_test(async(test) => {
+    await navigator.mediaDevices.getUserMedia({audio: true});
+    return navigator.mediaDevices.getUserMedia({audio: {deviceId: {exact:"none"}}}).then(
+        () => assert_not_reached("gum should fail"),
+        (e) => {
+            assert_true(e instanceof OverconstrainedError);
+            assert_equals(e.constraint, "deviceId", "constraint should be deviceId");
+        }
+    );
+}, "After grant");
+        </script>
+    </body>
+</html>

Modified: trunk/Source/WebKit/ChangeLog (241166 => 241167)


--- trunk/Source/WebKit/ChangeLog	2019-02-07 23:37:23 UTC (rev 241166)
+++ trunk/Source/WebKit/ChangeLog	2019-02-07 23:49:00 UTC (rev 241167)
@@ -1,3 +1,53 @@
+2019-02-07  Youenn Fablet  <you...@apple.com>
+
+        Filter out Overconstrainederror.constraint when getUserMedia is not granted
+        https://bugs.webkit.org/show_bug.cgi?id=194240
+
+        Reviewed by Eric Carlson.
+
+        Make sure in UIProcess to filter out constraint if either the page was not granted gum access or it has no persistent access.
+
+        Refactor UserMediaPermissionRequestManagerProxy to make the implementation easier to understand.
+
+        Covered by added test.
+
+        * UIProcess/UserMediaPermissionCheckProxy.cpp:
+        (WebKit::UserMediaPermissionCheckProxy::setUserMediaAccessInfo):
+        * UIProcess/UserMediaPermissionRequestManagerProxy.cpp:
+        (WebKit::UserMediaPermissionRequestManagerProxy::captureDevicesChanged):
+        (WebKit::UserMediaPermissionRequestManagerProxy::userMediaAccessWasGranted):
+        (WebKit::UserMediaPermissionRequestManagerProxy::grantAccess):
+        (WebKit::UserMediaPermissionRequestManagerProxy::getRequestAction):
+        (WebKit::UserMediaPermissionRequestManagerProxy::requestUserMediaPermissionForFrame):
+        (WebKit::UserMediaPermissionRequestManagerProxy::processUserMediaPermissionRequest):
+        (WebKit::UserMediaPermissionRequestManagerProxy::processUserMediaPermissionInvalidRequest):
+        (WebKit::UserMediaPermissionRequestManagerProxy::processUserMediaPermissionValidRequest):
+        (WebKit::UserMediaPermissionRequestManagerProxy::getUserMediaPermissionInfo):
+        (WebKit::UserMediaPermissionRequestManagerProxy::wasGrantedVideoOrAudioAccess):
+        (WebKit::UserMediaPermissionRequestManagerProxy::computeFilteredDeviceList):
+        (WebKit::UserMediaPermissionRequestManagerProxy::enumerateMediaDevicesForFrame):
+        (WebKit::UserMediaPermissionRequestManagerProxy::createPermissionRequest): Deleted.
+        * UIProcess/UserMediaPermissionRequestManagerProxy.h:
+        * UIProcess/UserMediaPermissionRequestProxy.h:
+        (WebKit::UserMediaPermissionRequestProxy::isPending const):
+        (WebKit::UserMediaPermissionRequestProxy::setEligibleVideoDeviceUIDs):
+        (WebKit::UserMediaPermissionRequestProxy::setEligibleAudioDeviceUIDs):
+        (WebKit::UserMediaPermissionRequestProxy::hasAudioDevice const):
+        (WebKit::UserMediaPermissionRequestProxy::hasVideoDevice const):
+        (WebKit::UserMediaPermissionRequestProxy::hasPersistentAccess const):
+        (WebKit::UserMediaPermissionRequestProxy::setHasPersistentAccess):
+        (WebKit::UserMediaPermissionRequestProxy::userMediaID const):
+        (WebKit::UserMediaPermissionRequestProxy::topLevelDocumentSecurityOrigin const):
+        (WebKit::UserMediaPermissionRequestProxy::userMediaDocumentSecurityOrigin const):
+        (WebKit::UserMediaPermissionRequestProxy::userRequest const):
+        (WebKit::UserMediaPermissionRequestProxy::setDeviceIdentifierHashSalt):
+        (WebKit::UserMediaPermissionRequestProxy::deviceIdentifierHashSalt const):
+        (WebKit::UserMediaPermissionRequestProxy::audioDevice const):
+        (WebKit::UserMediaPermissionRequestProxy::videoDevice const):
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::requestUserMediaPermissionForFrame):
+        * UIProcess/WebPageProxy.h:
+
 2019-02-07  Wenson Hsieh  <wenson_hs...@apple.com>
 
         [iOS] [WK2] Modernize autocorrection context code

Modified: trunk/Source/WebKit/UIProcess/UserMediaPermissionCheckProxy.cpp (241166 => 241167)


--- trunk/Source/WebKit/UIProcess/UserMediaPermissionCheckProxy.cpp	2019-02-07 23:37:23 UTC (rev 241166)
+++ trunk/Source/WebKit/UIProcess/UserMediaPermissionCheckProxy.cpp	2019-02-07 23:49:00 UTC (rev 241167)
@@ -41,20 +41,25 @@
 {
 }
 
+UserMediaPermissionCheckProxy::~UserMediaPermissionCheckProxy()
+{
+    invalidate();
+}
+
 void UserMediaPermissionCheckProxy::setUserMediaAccessInfo(bool allowed)
 {
     ASSERT(m_completionHandler);
+    complete(allowed);
+}
+
+void UserMediaPermissionCheckProxy::complete(Optional<bool> allowed)
+{
     if (!m_completionHandler)
         return;
 
-    m_completionHandler(allowed);
-    m_completionHandler = nullptr;
+    auto completionHandler = WTFMove(m_completionHandler);
+    completionHandler(allowed);
 }
 
-void UserMediaPermissionCheckProxy::invalidate()
-{
-    m_completionHandler = nullptr;
-}
-
 } // namespace WebKit
 

Modified: trunk/Source/WebKit/UIProcess/UserMediaPermissionCheckProxy.h (241166 => 241167)


--- trunk/Source/WebKit/UIProcess/UserMediaPermissionCheckProxy.h	2019-02-07 23:37:23 UTC (rev 241166)
+++ trunk/Source/WebKit/UIProcess/UserMediaPermissionCheckProxy.h	2019-02-07 23:49:00 UTC (rev 241167)
@@ -27,7 +27,7 @@
 
 #include "APIObject.h"
 #include <WebCore/MediaConstraints.h>
-#include <wtf/Function.h>
+#include <wtf/CompletionHandler.h>
 #include <wtf/text/WTFString.h>
 
 namespace WebCore {
@@ -39,7 +39,7 @@
 class UserMediaPermissionCheckProxy : public API::ObjectImpl<API::Object::Type::UserMediaPermissionCheck> {
 public:
 
-    using CompletionHandler = WTF::Function<void(bool allowed)>;
+    using CompletionHandler = WTF::CompletionHandler<void(Optional<bool> allowed)>;
 
     static Ref<UserMediaPermissionCheckProxy> create(uint64_t frameID, CompletionHandler&& handler, Ref<WebCore::SecurityOrigin>&& userMediaDocumentOrigin, Ref<WebCore::SecurityOrigin>&& topLevelDocumentOrigin)
     {
@@ -48,7 +48,7 @@
 
     void deny() { setUserMediaAccessInfo(false); }
     void setUserMediaAccessInfo(bool);
-    void invalidate();
+    void invalidate() { complete({ }); }
 
     uint64_t frameID() const { return m_frameID; }
     WebCore::SecurityOrigin& userMediaDocumentSecurityOrigin() { return m_userMediaDocumentSecurityOrigin.get(); }
@@ -56,7 +56,10 @@
     
 private:
     UserMediaPermissionCheckProxy(uint64_t frameID, CompletionHandler&&, Ref<WebCore::SecurityOrigin>&& userMediaDocumentOrigin, Ref<WebCore::SecurityOrigin>&& topLevelDocumentOrigin);
+    ~UserMediaPermissionCheckProxy();
 
+    void complete(Optional<bool> allowed);
+    
     uint64_t m_frameID;
     CompletionHandler m_completionHandler;
     Ref<WebCore::SecurityOrigin> m_userMediaDocumentSecurityOrigin;

Modified: trunk/Source/WebKit/UIProcess/UserMediaPermissionRequestManagerProxy.cpp (241166 => 241167)


--- trunk/Source/WebKit/UIProcess/UserMediaPermissionRequestManagerProxy.cpp	2019-02-07 23:37:23 UTC (rev 241166)
+++ trunk/Source/WebKit/UIProcess/UserMediaPermissionRequestManagerProxy.cpp	2019-02-07 23:49:00 UTC (rev 241167)
@@ -75,8 +75,6 @@
         request->invalidate();
     m_pendingUserMediaRequests.clear();
 
-    for (auto& request : m_pendingDeviceRequests.values())
-        request->invalidate();
     m_pendingDeviceRequests.clear();
 }
 
@@ -92,23 +90,18 @@
     if (!m_page.isValid() || !m_page.mainFrame())
         return;
 
-    auto requestID = generateRequestID();
-    auto handler = [this, weakThis = makeWeakPtr(*this), requestID](bool originHasPersistentAccess) mutable {
-        if (!weakThis)
+    auto handler = [this](Optional<bool> originHasPersistentAccess) mutable {
+        if (!originHasPersistentAccess || !m_page.isValid())
             return;
 
-        auto pendingRequest = m_pendingDeviceRequests.take(requestID);
-        if (!pendingRequest || !m_page.isValid())
+        if (m_grantedRequests.isEmpty() && !*originHasPersistentAccess)
             return;
 
-        if (m_grantedRequests.isEmpty() && !originHasPersistentAccess)
-            return;
-
         m_page.process().send(Messages::WebPage::CaptureDevicesChanged(), m_page.pageID());
     };
 
     auto origin = WebCore::SecurityOrigin::create(m_page.mainFrame()->url());
-    getUserMediaPermissionInfo(requestID, m_page.mainFrame()->frameID(), WTFMove(handler), origin.get(), WTFMove(origin));
+    getUserMediaPermissionInfo(m_page.mainFrame()->frameID(), origin.get(), WTFMove(origin), WTFMove(handler));
 #endif
 }
 
@@ -117,13 +110,6 @@
     invalidatePendingRequests();
 }
 
-Ref<UserMediaPermissionRequestProxy> UserMediaPermissionRequestManagerProxy::createPermissionRequest(uint64_t userMediaID, uint64_t mainFrameID, uint64_t frameID, Ref<SecurityOrigin>&& userMediaDocumentOrigin, Ref<SecurityOrigin>&& topLevelDocumentOrigin, Vector<CaptureDevice>&& audioDevices, Vector<CaptureDevice>&& videoDevices, MediaStreamRequest&& request)
-{
-    auto permissionRequest = UserMediaPermissionRequestProxy::create(*this, userMediaID, mainFrameID, frameID, WTFMove(userMediaDocumentOrigin), WTFMove(topLevelDocumentOrigin), WTFMove(audioDevices), WTFMove(videoDevices), WTFMove(request));
-    m_pendingUserMediaRequests.add(userMediaID, permissionRequest.ptr());
-    return permissionRequest;
-}
-
 #if ENABLE(MEDIA_STREAM)
 static uint64_t toWebCore(UserMediaPermissionRequestProxy::UserMediaAccessDenialReason reason)
 {
@@ -188,15 +174,18 @@
     if (!request)
         return;
 
-    m_page.websiteDataStore().deviceIdHashSaltStorage().deviceIdHashSaltForOrigin(request->userMediaDocumentSecurityOrigin(), request->topLevelDocumentSecurityOrigin(), [this, weakThis = makeWeakPtr(*this), userMediaID, audioDevice = WTFMove(audioDevice), videoDevice = WTFMove(videoDevice), localRequest = request.copyRef()] (String&& deviceIDHashSalt) mutable {
+    auto& userMediaDocumentSecurityOrigin = request->userMediaDocumentSecurityOrigin();
+    auto& topLevelDocumentSecurityOrigin = request->topLevelDocumentSecurityOrigin();
+    m_page.websiteDataStore().deviceIdHashSaltStorage().deviceIdHashSaltForOrigin(userMediaDocumentSecurityOrigin, topLevelDocumentSecurityOrigin, [this, weakThis = makeWeakPtr(*this), request = request.releaseNonNull()] (String&& deviceIDHashSalt) mutable {
         if (!weakThis)
             return;
-        if (grantAccess(userMediaID, WTFMove(audioDevice), WTFMove(videoDevice), WTFMove(deviceIDHashSalt))) {
-            m_grantedRequests.append(localRequest.releaseNonNull());
-            if (m_hasFilteredDeviceList)
-                captureDevicesChanged();
-            m_hasFilteredDeviceList = false;
-        }
+        if (!grantAccess(request))
+            return;
+
+        m_grantedRequests.append(WTFMove(request));
+        if (m_hasFilteredDeviceList)
+            captureDevicesChanged();
+        m_hasFilteredDeviceList = false;
     });
 #else
     UNUSED_PARAM(userMediaID);
@@ -266,14 +255,14 @@
     return false;
 }
 
-bool UserMediaPermissionRequestManagerProxy::grantAccess(uint64_t userMediaID, const CaptureDevice audioDevice, const CaptureDevice videoDevice, const String& deviceIdentifierHashSalt)
+bool UserMediaPermissionRequestManagerProxy::grantAccess(const UserMediaPermissionRequestProxy& request)
 {
-    if (!UserMediaProcessManager::singleton().willCreateMediaStream(*this, !!audioDevice, !!videoDevice)) {
-        denyRequest(userMediaID, UserMediaPermissionRequestProxy::UserMediaAccessDenialReason::OtherFailure, "Unable to extend sandbox.");
+    if (!UserMediaProcessManager::singleton().willCreateMediaStream(*this, request.hasAudioDevice(), request.hasVideoDevice())) {
+        denyRequest(request.userMediaID(), UserMediaPermissionRequestProxy::UserMediaAccessDenialReason::OtherFailure, "Unable to extend sandbox.");
         return false;
     }
 
-    m_page.process().send(Messages::WebPage::UserMediaAccessWasGranted(userMediaID, audioDevice, videoDevice, deviceIdentifierHashSalt), m_page.pageID());
+    m_page.process().send(Messages::WebPage::UserMediaAccessWasGranted(request.userMediaID(), request.audioDevice(), request.videoDevice(), request.deviceIdentifierHashSalt()), m_page.pageID());
     return true;
 }
 #endif
@@ -296,25 +285,26 @@
 }
 
 #if ENABLE(MEDIA_STREAM)
-UserMediaPermissionRequestManagerProxy::RequestAction UserMediaPermissionRequestManagerProxy::getRequestAction(uint64_t frameID, SecurityOrigin& userMediaDocumentOrigin, SecurityOrigin& topLevelDocumentOrigin, const MediaStreamRequest& userRequest, Vector<CaptureDevice>& audioDevices, Vector<CaptureDevice>& videoDevices)
+UserMediaPermissionRequestManagerProxy::RequestAction UserMediaPermissionRequestManagerProxy::getRequestAction(const UserMediaPermissionRequestProxy& request)
 {
-    bool requestingScreenCapture = userRequest.type == MediaStreamRequest::Type::DisplayMedia;
-    ASSERT(!(requestingScreenCapture && videoDevices.isEmpty()));
-    ASSERT(!(requestingScreenCapture && !audioDevices.isEmpty()));
-    bool requestingCamera = !requestingScreenCapture && !videoDevices.isEmpty();
-    bool requestingMicrophone = !audioDevices.isEmpty();
+    bool requestingScreenCapture = request.requestType() == MediaStreamRequest::Type::DisplayMedia;
+    bool requestingCamera = !requestingScreenCapture && request.hasVideoDevice();
+    bool requestingMicrophone = request.hasAudioDevice();
 
-    if (wasRequestDenied(frameID, userMediaDocumentOrigin, topLevelDocumentOrigin, requestingMicrophone, requestingCamera, requestingScreenCapture))
+    ASSERT(!(requestingScreenCapture && !request.hasVideoDevice()));
+    ASSERT(!(requestingScreenCapture && requestingMicrophone));
+
+    if (wasRequestDenied(request.frameID(), request.userMediaDocumentSecurityOrigin(), request.topLevelDocumentSecurityOrigin(), requestingMicrophone, requestingCamera, requestingScreenCapture))
         return RequestAction::Deny;
 
-    if (userRequest.type == MediaStreamRequest::Type::DisplayMedia)
+    if (request.requestType() == MediaStreamRequest::Type::DisplayMedia)
         return RequestAction::Prompt;
 
-    return searchForGrantedRequest(frameID, userMediaDocumentOrigin, topLevelDocumentOrigin, requestingMicrophone, requestingCamera) ? RequestAction::Grant : RequestAction::Prompt;
+    return searchForGrantedRequest(request.frameID(), request.userMediaDocumentSecurityOrigin(), request.topLevelDocumentSecurityOrigin(), requestingMicrophone, requestingCamera) ? RequestAction::Grant : RequestAction::Prompt;
 }
 #endif
 
-void UserMediaPermissionRequestManagerProxy::requestUserMediaPermissionForFrame(uint64_t userMediaID, uint64_t frameID, Ref<SecurityOrigin>&& userMediaDocumentOrigin, Ref<SecurityOrigin>&& topLevelDocumentOrigin, const MediaStreamRequest& userRequest)
+void UserMediaPermissionRequestManagerProxy::requestUserMediaPermissionForFrame(uint64_t userMediaID, uint64_t frameID, Ref<SecurityOrigin>&& userMediaDocumentOrigin, Ref<SecurityOrigin>&& topLevelDocumentOrigin, MediaStreamRequest&& userRequest)
 {
 #if ENABLE(MEDIA_STREAM)
     if (!UserMediaProcessManager::singleton().captureEnabled()) {
@@ -323,95 +313,62 @@
         return;
     }
 
-    RealtimeMediaSourceCenter::InvalidConstraintsHandler invalidHandler = [this, userMediaID](const String& invalidConstraint) {
-        if (!m_page.isValid())
-            return;
+    if (!m_page.isValid())
+        return;
 
-        denyRequest(userMediaID, UserMediaPermissionRequestProxy::UserMediaAccessDenialReason::InvalidConstraint, invalidConstraint);
-    };
+    auto userMediaOrigin = API::SecurityOrigin::create(userMediaDocumentOrigin.get());
+    auto topLevelOrigin = API::SecurityOrigin::create(topLevelDocumentOrigin.get());
 
-    auto validHandler = [this, userMediaID, frameID, userMediaDocumentOrigin = userMediaDocumentOrigin.copyRef(), topLevelDocumentOrigin = topLevelDocumentOrigin.copyRef(), localUserRequest = userRequest](Vector<CaptureDevice>&& audioDevices, Vector<CaptureDevice>&& videoDevices, String&& deviceIdentifierHashSalt) mutable {
-        if (!m_page.isValid() || !m_page.mainFrame())
-            return;
+    auto request = m_pendingUserMediaRequests.add(userMediaID, UserMediaPermissionRequestProxy::create(*this, userMediaID, m_page.mainFrame()->frameID(), frameID, WTFMove(userMediaDocumentOrigin), WTFMove(topLevelDocumentOrigin), { }, { }, WTFMove(userRequest))).iterator->value.copyRef();
 
-        if (videoDevices.isEmpty() && audioDevices.isEmpty()) {
-            denyRequest(userMediaID, UserMediaPermissionRequestProxy::UserMediaAccessDenialReason::NoConstraints, emptyString());
+    getUserMediaPermissionInfo(frameID, request->userMediaDocumentSecurityOrigin(), request->topLevelDocumentSecurityOrigin(), [this, request = request.releaseNonNull()](Optional<bool> hasPersistentAccess) mutable {
+        if (!request->isPending())
             return;
-        }
 
-        auto action = "" userMediaDocumentOrigin.get(), topLevelDocumentOrigin.get(), localUserRequest, audioDevices, videoDevices);
-        if (action == RequestAction::Deny) {
-            denyRequest(userMediaID, UserMediaPermissionRequestProxy::UserMediaAccessDenialReason::PermissionDenied, emptyString());
+        if (!hasPersistentAccess) {
+            request->deny(UserMediaPermissionRequestProxy::UserMediaAccessDenialReason::OtherFailure);
             return;
         }
 
-        if (action == RequestAction::Grant) {
-            ASSERT(localUserRequest.type != MediaStreamRequest::Type::DisplayMedia);
+        processUserMediaPermissionRequest(WTFMove(request), *hasPersistentAccess);
+    });
+}
 
-            if (m_page.isViewVisible()) {
-                // We select the first available devices, but the current client API allows client to select which device to pick.
-                // FIXME: Remove the possiblity for the client to do the device selection.
-                auto audioDevice = !audioDevices.isEmpty() ? audioDevices[0] : CaptureDevice();
-                auto videoDevice = !videoDevices.isEmpty() ? videoDevices[0] : CaptureDevice();
-                grantAccess(userMediaID, WTFMove(audioDevice), WTFMove(videoDevice), WTFMove(deviceIdentifierHashSalt));
-            } else
-                m_pregrantedRequests.append(createPermissionRequest(userMediaID, m_page.mainFrame()->frameID(), frameID, WTFMove(userMediaDocumentOrigin), WTFMove(topLevelDocumentOrigin), WTFMove(audioDevices), WTFMove(videoDevices), WTFMove(localUserRequest)));
+void UserMediaPermissionRequestManagerProxy::processUserMediaPermissionRequest(Ref<UserMediaPermissionRequestProxy>&& request, bool hasPersistentAccess)
+{
+    if (hasPersistentAccess)
+        request->setHasPersistentAccess();
 
+    auto& userMediaDocumentSecurityOrigin = request->userMediaDocumentSecurityOrigin();
+    auto& topLevelDocumentSecurityOrigin = request->topLevelDocumentSecurityOrigin();
+    m_page.websiteDataStore().deviceIdHashSaltStorage().deviceIdHashSaltForOrigin(userMediaDocumentSecurityOrigin, topLevelDocumentSecurityOrigin, [this, request = WTFMove(request)] (String&& deviceIDHashSalt) mutable {
+        if (!request->isPending())
             return;
-        }
 
-        auto userMediaOrigin = API::SecurityOrigin::create(userMediaDocumentOrigin.get());
-        auto topLevelOrigin = API::SecurityOrigin::create(topLevelDocumentOrigin.get());
-        auto pendingRequest = createPermissionRequest(userMediaID, m_page.mainFrame()->frameID(), frameID, WTFMove(userMediaDocumentOrigin), WTFMove(topLevelDocumentOrigin), WTFMove(audioDevices), WTFMove(videoDevices), WTFMove(localUserRequest));
+        RealtimeMediaSourceCenter::InvalidConstraintsHandler invalidHandler = [this, request = request.copyRef()](const String& invalidConstraint) {
+            if (!request->isPending())
+                return;
 
-        if (m_page.isControlledByAutomation()) {
-            if (WebAutomationSession* automationSession = m_page.process().processPool().automationSession()) {
-                if (automationSession->shouldAllowGetUserMediaForPage(m_page))
-                    pendingRequest->allow();
-                else
-                    userMediaAccessWasDenied(userMediaID, UserMediaPermissionRequestProxy::UserMediaAccessDenialReason::PermissionDenied);
-
+            if (!m_page.isValid())
                 return;
-            }
-        }
 
-        if (m_page.preferences().mockCaptureDevicesEnabled() && !m_page.preferences().mockCaptureDevicesPromptEnabled()) {
-            pendingRequest->allow();
-            return;
-        }
+            processUserMediaPermissionInvalidRequest(request.get(), invalidConstraint);
+        };
 
-        // If page navigated, there is no need to call the page client for authorization.
-        auto* webFrame = m_page.process().webFrame(frameID);
+        auto validHandler = [this, request = request.copyRef()](Vector<CaptureDevice>&& audioDevices, Vector<CaptureDevice>&& videoDevices, String&& deviceIdentifierHashSalt) mutable {
+            if (!request->isPending())
+                return;
 
-        if (!webFrame || !SecurityOrigin::createFromString(m_page.pageLoadState().activeURL())->isSameSchemeHostPort(topLevelOrigin->securityOrigin())) {
-            denyRequest(userMediaID, UserMediaPermissionRequestProxy::UserMediaAccessDenialReason::NoConstraints, emptyString());
-            return;
-        }
+            if (!m_page.isValid() || !m_page.mainFrame())
+                return;
 
-        // FIXME: Remove webFrame, userMediaOrigin and topLevelOrigin from this uiClient API call.
-        m_page.uiClient().decidePolicyForUserMediaPermissionRequest(m_page, *webFrame, WTFMove(userMediaOrigin), WTFMove(topLevelOrigin), pendingRequest.get());
-    };
+            processUserMediaPermissionValidRequest(WTFMove(request), WTFMove(audioDevices), WTFMove(videoDevices), WTFMove(deviceIdentifierHashSalt));
+        };
 
-    auto requestID = generateRequestID();
-    auto havePermissionInfoHandler = [this, weakThis = makeWeakPtr(*this), requestID, validHandler = WTFMove(validHandler), invalidHandler = WTFMove(invalidHandler), localUserRequest = userRequest](bool originHasPersistentAccess) mutable {
-        if (!weakThis)
-            return;
-
-        auto pendingRequest = m_pendingDeviceRequests.take(requestID);
-        if (!pendingRequest)
-            return;
-
-        if (!m_page.isValid())
-            return;
-
         syncWithWebCorePrefs();
 
-        m_page.websiteDataStore().deviceIdHashSaltStorage().deviceIdHashSaltForOrigin(pendingRequest.value()->userMediaDocumentSecurityOrigin(), pendingRequest.value()->topLevelDocumentSecurityOrigin(), [validHandler = WTFMove(validHandler), invalidHandler = WTFMove(invalidHandler), localUserRequest = localUserRequest] (String&& deviceIDHashSalt) mutable {
-            RealtimeMediaSourceCenter::singleton().validateRequestConstraints(WTFMove(validHandler), WTFMove(invalidHandler), WTFMove(localUserRequest), WTFMove(deviceIDHashSalt));
-        });
-    };
-
-    getUserMediaPermissionInfo(requestID, frameID, WTFMove(havePermissionInfoHandler), WTFMove(userMediaDocumentOrigin), WTFMove(topLevelDocumentOrigin));
+        RealtimeMediaSourceCenter::singleton().validateRequestConstraints(WTFMove(validHandler), WTFMove(invalidHandler), request->userRequest(), WTFMove(deviceIDHashSalt));
+    });
 #else
     UNUSED_PARAM(userMediaID);
     UNUSED_PARAM(frameID);
@@ -422,19 +379,93 @@
 }
 
 #if ENABLE(MEDIA_STREAM)
-void UserMediaPermissionRequestManagerProxy::getUserMediaPermissionInfo(uint64_t requestID, uint64_t frameID, UserMediaPermissionCheckProxy::CompletionHandler&& handler, Ref<SecurityOrigin>&& userMediaDocumentOrigin, Ref<SecurityOrigin>&& topLevelDocumentOrigin)
+void UserMediaPermissionRequestManagerProxy::processUserMediaPermissionInvalidRequest(const UserMediaPermissionRequestProxy& request, const String& invalidConstraint)
 {
+    bool filterConstraint = !request.hasPersistentAccess() && !wasGrantedVideoOrAudioAccess(request.frameID(), request.userMediaDocumentSecurityOrigin(), request.topLevelDocumentSecurityOrigin());
+
+    denyRequest(request.userMediaID(), UserMediaPermissionRequestProxy::UserMediaAccessDenialReason::InvalidConstraint, filterConstraint ? String { } : invalidConstraint);
+}
+
+void UserMediaPermissionRequestManagerProxy::processUserMediaPermissionValidRequest(Ref<UserMediaPermissionRequestProxy>&& request, Vector<CaptureDevice>&& audioDevices, Vector<CaptureDevice>&& videoDevices, String&& deviceIdentifierHashSalt)
+{
+    if (videoDevices.isEmpty() && audioDevices.isEmpty()) {
+        denyRequest(request->userMediaID(), UserMediaPermissionRequestProxy::UserMediaAccessDenialReason::NoConstraints, emptyString());
+        return;
+    }
+
+    request->setDeviceIdentifierHashSalt(WTFMove(deviceIdentifierHashSalt));
+    request->setEligibleVideoDeviceUIDs(WTFMove(videoDevices));
+    request->setEligibleAudioDeviceUIDs(WTFMove(audioDevices));
+
+    auto action = ""
+    if (action == RequestAction::Deny) {
+        denyRequest(request->userMediaID(), UserMediaPermissionRequestProxy::UserMediaAccessDenialReason::PermissionDenied, emptyString());
+        return;
+    }
+
+    if (action == RequestAction::Grant) {
+        ASSERT(request->requestType() != MediaStreamRequest::Type::DisplayMedia);
+
+        if (m_page.isViewVisible())
+            grantAccess(request);
+        else
+            m_pregrantedRequests.append(WTFMove(request));
+
+        return;
+    }
+
+    if (m_page.isControlledByAutomation()) {
+        if (WebAutomationSession* automationSession = m_page.process().processPool().automationSession()) {
+            if (automationSession->shouldAllowGetUserMediaForPage(m_page))
+                request->allow();
+            else
+                userMediaAccessWasDenied(request->userMediaID(), UserMediaPermissionRequestProxy::UserMediaAccessDenialReason::PermissionDenied);
+
+            return;
+        }
+    }
+
+    if (m_page.preferences().mockCaptureDevicesEnabled() && !m_page.preferences().mockCaptureDevicesPromptEnabled()) {
+        request->allow();
+        return;
+    }
+
+    // If page navigated, there is no need to call the page client for authorization.
+    auto* webFrame = m_page.process().webFrame(request->frameID());
+
+    if (!webFrame || !SecurityOrigin::createFromString(m_page.pageLoadState().activeURL())->isSameSchemeHostPort(request->topLevelDocumentSecurityOrigin())) {
+        denyRequest(request->userMediaID(), UserMediaPermissionRequestProxy::UserMediaAccessDenialReason::NoConstraints, emptyString());
+        return;
+    }
+
+    // FIXME: Remove webFrame, userMediaOrigin and topLevelOrigin from this uiClient API call.
+    auto userMediaOrigin = API::SecurityOrigin::create(request->userMediaDocumentSecurityOrigin());
+    auto topLevelOrigin = API::SecurityOrigin::create(request->topLevelDocumentSecurityOrigin());
+    m_page.uiClient().decidePolicyForUserMediaPermissionRequest(m_page, *webFrame, WTFMove(userMediaOrigin), WTFMove(topLevelOrigin), request);
+}
+
+void UserMediaPermissionRequestManagerProxy::getUserMediaPermissionInfo(uint64_t frameID, Ref<SecurityOrigin>&& userMediaDocumentOrigin, Ref<SecurityOrigin>&& topLevelDocumentOrigin, CompletionHandler<void(Optional<bool>)>&& handler)
+{
     auto* webFrame = m_page.process().webFrame(frameID);
     if (!webFrame || !SecurityOrigin::createFromString(m_page.pageLoadState().activeURL())->isSameSchemeHostPort(topLevelDocumentOrigin.get())) {
-        handler(false);
+        handler({ });
         return;
     }
 
     auto userMediaOrigin = API::SecurityOrigin::create(userMediaDocumentOrigin.get());
     auto topLevelOrigin = API::SecurityOrigin::create(topLevelDocumentOrigin.get());
-    auto request = UserMediaPermissionCheckProxy::create(frameID, WTFMove(handler), WTFMove(userMediaDocumentOrigin), WTFMove(topLevelDocumentOrigin));
 
-    m_pendingDeviceRequests.add(requestID, request.copyRef());
+    auto requestID = generateRequestID();
+    m_pendingDeviceRequests.add(requestID);
+
+    auto request = UserMediaPermissionCheckProxy::create(frameID, [this, weakThis = makeWeakPtr(*this), requestID, handler = WTFMove(handler)](Optional<bool> allowed) mutable {
+        if (!weakThis || !m_pendingDeviceRequests.remove(requestID) || !allowed) {
+            handler({ });
+            return;
+        }
+        handler(*allowed);
+    }, WTFMove(userMediaDocumentOrigin), WTFMove(topLevelDocumentOrigin));
+
     // FIXME: Remove webFrame, userMediaOrigin and topLevelOrigin from this uiClient API call.
     m_page.uiClient().checkUserMediaPermissionForOrigin(m_page, *webFrame, userMediaOrigin.get(), topLevelOrigin.get(), request.get());
 }
@@ -457,12 +488,9 @@
 
     return false;
 }
-#endif
 
-void UserMediaPermissionRequestManagerProxy::enumerateMediaDevicesForFrame(uint64_t userMediaID, uint64_t frameID, Ref<SecurityOrigin>&& userMediaDocumentOrigin, Ref<SecurityOrigin>&& topLevelDocumentOrigin)
+Vector<CaptureDevice> UserMediaPermissionRequestManagerProxy::computeFilteredDeviceList(bool revealIdsAndLabels, const String& deviceIDHashSalt)
 {
-#if ENABLE(MEDIA_STREAM)
-
 #if PLATFORM(IOS_FAMILY)
     static const int defaultMaximumCameraCount = 2;
 #else
@@ -470,20 +498,57 @@
 #endif
     static const int defaultMaximumMicrophoneCount = 1;
 
-    auto requestID = generateRequestID();
-    auto completionHandler = [this, weakThis = makeWeakPtr(*this), requestID, userMediaID, requestOrigin = userMediaDocumentOrigin.copyRef(), topOrigin = topLevelDocumentOrigin.copyRef()](bool originHasPersistentAccess) mutable {
-        if (!weakThis)
+    auto devices = RealtimeMediaSourceCenter::singleton().getMediaStreamDevices();
+    int cameraCount = 0;
+    int microphoneCount = 0;
+
+    Vector<CaptureDevice> filteredDevices;
+    for (const auto& device : devices) {
+        if (!device.enabled() || (device.type() != WebCore::CaptureDevice::DeviceType::Camera && device.type() != WebCore::CaptureDevice::DeviceType::Microphone))
+            continue;
+
+        if (!revealIdsAndLabels) {
+            if (device.type() == WebCore::CaptureDevice::DeviceType::Camera && ++cameraCount > defaultMaximumCameraCount)
+                continue;
+            if (device.type() == WebCore::CaptureDevice::DeviceType::Microphone && ++microphoneCount > defaultMaximumMicrophoneCount)
+                continue;
+        }
+
+        auto label = emptyString();
+        auto id = emptyString();
+        auto groupId = emptyString();
+        if (revealIdsAndLabels) {
+            label = device.label();
+            id = RealtimeMediaSourceCenter::singleton().hashStringWithSalt(device.persistentId(), deviceIDHashSalt);
+            groupId = RealtimeMediaSourceCenter::singleton().hashStringWithSalt(device.groupId(), deviceIDHashSalt);
+        }
+
+        filteredDevices.append(CaptureDevice(id, device.type(), label, groupId));
+    }
+
+    m_hasFilteredDeviceList = !revealIdsAndLabels;
+    return filteredDevices;
+}
+#endif
+
+void UserMediaPermissionRequestManagerProxy::enumerateMediaDevicesForFrame(uint64_t userMediaID, uint64_t frameID, Ref<SecurityOrigin>&& userMediaDocumentOrigin, Ref<SecurityOrigin>&& topLevelDocumentOrigin)
+{
+#if ENABLE(MEDIA_STREAM)
+    auto completionHandler = [this, userMediaID, frameID, userMediaDocumentOrigin = userMediaDocumentOrigin.copyRef(), topLevelDocumentOrigin = topLevelDocumentOrigin.copyRef()](Optional<bool> originHasPersistentAccess) mutable {
+        if (!originHasPersistentAccess)
             return;
 
         if (!m_page.isValid())
             return;
 
-        m_page.websiteDataStore().deviceIdHashSaltStorage().deviceIdHashSaltForOrigin(requestOrigin.get(), topOrigin.get(), [this, weakThis = WTFMove(weakThis), requestID, userMediaID, &originHasPersistentAccess] (String&& deviceIDHashSalt) {
-            if (!weakThis)
+        auto requestID = generateRequestID();
+        m_pendingDeviceRequests.add(requestID);
+
+        auto& requestOrigin = userMediaDocumentOrigin.get();
+        auto& topOrigin = topLevelDocumentOrigin.get();
+        m_page.websiteDataStore().deviceIdHashSaltStorage().deviceIdHashSaltForOrigin(requestOrigin, topOrigin, [this, weakThis = makeWeakPtr(*this), requestID, frameID, userMediaID, userMediaDocumentOrigin = WTFMove(userMediaDocumentOrigin), topLevelDocumentOrigin = WTFMove(topLevelDocumentOrigin), originHasPersistentAccess = *originHasPersistentAccess] (String&& deviceIDHashSalt) {
+            if (!weakThis || !m_pendingDeviceRequests.remove(requestID))
                 return;
-            auto pendingRequest = m_pendingDeviceRequests.take(requestID);
-            if (!pendingRequest)
-                return;
 
             if (!m_page.isValid())
                 return;
@@ -490,43 +555,13 @@
 
             syncWithWebCorePrefs();
 
-            auto devices = RealtimeMediaSourceCenter::singleton().getMediaStreamDevices();
-            auto& request = *pendingRequest;
-            bool revealIdsAndLabels = originHasPersistentAccess || wasGrantedVideoOrAudioAccess(request->frameID(), request->userMediaDocumentSecurityOrigin(), request->topLevelDocumentSecurityOrigin());
-            int cameraCount = 0;
-            int microphoneCount = 0;
+            bool revealIdsAndLabels = originHasPersistentAccess || wasGrantedVideoOrAudioAccess(frameID, userMediaDocumentOrigin.get(), topLevelDocumentOrigin.get());
 
-            Vector<CaptureDevice> filteredDevices;
-            for (const auto& device : devices) {
-                if (!device.enabled() || (device.type() != WebCore::CaptureDevice::DeviceType::Camera && device.type() != WebCore::CaptureDevice::DeviceType::Microphone))
-                    continue;
-
-                if (!revealIdsAndLabels) {
-                    if (device.type() == WebCore::CaptureDevice::DeviceType::Camera && ++cameraCount > defaultMaximumCameraCount)
-                        continue;
-                    if (device.type() == WebCore::CaptureDevice::DeviceType::Microphone && ++microphoneCount > defaultMaximumMicrophoneCount)
-                        continue;
-                }
-
-                auto label = emptyString();
-                auto id = emptyString();
-                auto groupId = emptyString();
-                if (revealIdsAndLabels) {
-                    label = device.label();
-                    id = RealtimeMediaSourceCenter::singleton().hashStringWithSalt(device.persistentId(), deviceIDHashSalt);
-                    groupId = RealtimeMediaSourceCenter::singleton().hashStringWithSalt(device.groupId(), deviceIDHashSalt);
-                }
-
-                filteredDevices.append(CaptureDevice(id, device.type(), label, groupId));
-            }
-
-            m_hasFilteredDeviceList = !revealIdsAndLabels;
-
-            m_page.process().send(Messages::WebPage::DidCompleteMediaDeviceEnumeration(userMediaID, WTFMove(filteredDevices), WTFMove(deviceIDHashSalt), originHasPersistentAccess), m_page.pageID());
+            m_page.process().send(Messages::WebPage::DidCompleteMediaDeviceEnumeration { userMediaID, computeFilteredDeviceList(revealIdsAndLabels, deviceIDHashSalt), deviceIDHashSalt, originHasPersistentAccess }, m_page.pageID());
         });
     };
 
-    getUserMediaPermissionInfo(requestID, frameID, WTFMove(completionHandler), WTFMove(userMediaDocumentOrigin), WTFMove(topLevelDocumentOrigin));
+    getUserMediaPermissionInfo(frameID, WTFMove(userMediaDocumentOrigin), WTFMove(topLevelDocumentOrigin), WTFMove(completionHandler));
 #else
     UNUSED_PARAM(userMediaID);
     UNUSED_PARAM(frameID);

Modified: trunk/Source/WebKit/UIProcess/UserMediaPermissionRequestManagerProxy.h (241166 => 241167)


--- trunk/Source/WebKit/UIProcess/UserMediaPermissionRequestManagerProxy.h	2019-02-07 23:37:23 UTC (rev 241166)
+++ trunk/Source/WebKit/UIProcess/UserMediaPermissionRequestManagerProxy.h	2019-02-07 23:49:00 UTC (rev 241167)
@@ -23,6 +23,7 @@
 #include "UserMediaPermissionRequestProxy.h"
 #include <WebCore/MediaProducer.h>
 #include <WebCore/SecurityOrigin.h>
+#include <wtf/CompletionHandler.h>
 #include <wtf/HashMap.h>
 #include <wtf/RunLoop.h>
 #include <wtf/Seconds.h>
@@ -48,7 +49,7 @@
 
     void invalidatePendingRequests();
 
-    void requestUserMediaPermissionForFrame(uint64_t userMediaID, uint64_t frameID, Ref<WebCore::SecurityOrigin>&&  userMediaDocumentOrigin, Ref<WebCore::SecurityOrigin>&& topLevelDocumentOrigin, const WebCore::MediaStreamRequest&);
+    void requestUserMediaPermissionForFrame(uint64_t userMediaID, uint64_t frameID, Ref<WebCore::SecurityOrigin>&&  userMediaDocumentOrigin, Ref<WebCore::SecurityOrigin>&& topLevelDocumentOrigin, WebCore::MediaStreamRequest&&);
 
     void resetAccess(uint64_t mainFrameID);
     void viewIsBecomingVisible();
@@ -71,12 +72,12 @@
     Ref<UserMediaPermissionRequestProxy> createPermissionRequest(uint64_t userMediaID, uint64_t mainFrameID, uint64_t frameID, Ref<WebCore::SecurityOrigin>&& userMediaDocumentOrigin, Ref<WebCore::SecurityOrigin>&& topLevelDocumentOrigin, Vector<WebCore::CaptureDevice>&& audioDevices, Vector<WebCore::CaptureDevice>&& videoDevices, WebCore::MediaStreamRequest&&);
     void denyRequest(uint64_t userMediaID, UserMediaPermissionRequestProxy::UserMediaAccessDenialReason, const String& invalidConstraint);
 #if ENABLE(MEDIA_STREAM)
-    bool grantAccess(uint64_t userMediaID, const WebCore::CaptureDevice audioDevice, const WebCore::CaptureDevice videoDevice, const String& deviceIdentifierHashSalt);
+    bool grantAccess(const UserMediaPermissionRequestProxy&);
 
     const UserMediaPermissionRequestProxy* searchForGrantedRequest(uint64_t frameID, const WebCore::SecurityOrigin& userMediaDocumentOrigin, const WebCore::SecurityOrigin& topLevelDocumentOrigin, bool needsAudio, bool needsVideo) const;
     bool wasRequestDenied(uint64_t mainFrameID, const WebCore::SecurityOrigin& userMediaDocumentOrigin, const WebCore::SecurityOrigin& topLevelDocumentOrigin, bool needsAudio, bool needsVideo, bool needsScreenCapture);
 
-    void getUserMediaPermissionInfo(uint64_t requestID, uint64_t frameID, UserMediaPermissionCheckProxy::CompletionHandler&&, Ref<WebCore::SecurityOrigin>&& userMediaDocumentOrigin, Ref<WebCore::SecurityOrigin>&& topLevelDocumentOrigin);
+    void getUserMediaPermissionInfo(uint64_t frameID, Ref<WebCore::SecurityOrigin>&& userMediaDocumentOrigin, Ref<WebCore::SecurityOrigin>&& topLevelDocumentOrigin, CompletionHandler<void(Optional<bool>)>&&);
 
     enum class RequestAction {
         Deny,
@@ -83,15 +84,21 @@
         Grant,
         Prompt
     };
-    RequestAction getRequestAction(uint64_t frameID, WebCore::SecurityOrigin& userMediaDocumentOrigin, WebCore::SecurityOrigin& topLevelDocumentOrigin, const WebCore::MediaStreamRequest&, Vector<WebCore::CaptureDevice>& audioDevices, Vector<WebCore::CaptureDevice>& videoDevices);
+    RequestAction getRequestAction(const UserMediaPermissionRequestProxy&);
 
     bool wasGrantedVideoOrAudioAccess(uint64_t, const WebCore::SecurityOrigin& userMediaDocumentOrigin, const WebCore::SecurityOrigin& topLevelDocumentOrigin);
+
+    Vector<WebCore::CaptureDevice> computeFilteredDeviceList(bool revealIdsAndLabels, const String& deviceIDHashSalt);
+
+    void processUserMediaPermissionRequest(Ref<UserMediaPermissionRequestProxy>&&, bool hasPersistentAccess);
+    void processUserMediaPermissionInvalidRequest(const UserMediaPermissionRequestProxy&, const String& invalidConstraint);
+    void processUserMediaPermissionValidRequest(Ref<UserMediaPermissionRequestProxy>&&, Vector<WebCore::CaptureDevice>&& audioDevices, Vector<WebCore::CaptureDevice>&& videoDevices, String&& deviceIdentifierHashSalt);
 #endif
 
     void watchdogTimerFired();
 
     HashMap<uint64_t, RefPtr<UserMediaPermissionRequestProxy>> m_pendingUserMediaRequests;
-    HashMap<uint64_t, Ref<UserMediaPermissionCheckProxy>> m_pendingDeviceRequests;
+    HashSet<uint64_t> m_pendingDeviceRequests;
 
     WebPageProxy& m_page;
 

Modified: trunk/Source/WebKit/UIProcess/UserMediaPermissionRequestProxy.h (241166 => 241167)


--- trunk/Source/WebKit/UIProcess/UserMediaPermissionRequestProxy.h	2019-02-07 23:37:23 UTC (rev 241166)
+++ trunk/Source/WebKit/UIProcess/UserMediaPermissionRequestProxy.h	2019-02-07 23:49:00 UTC (rev 241167)
@@ -48,21 +48,42 @@
     void deny(UserMediaAccessDenialReason = UserMediaAccessDenialReason::UserMediaDisabled);
 
     void invalidate();
+    bool isPending() const { return m_manager; }
 
     bool requiresAudioCapture() const { return m_eligibleAudioDevices.size(); }
     bool requiresVideoCapture() const { return !requiresDisplayCapture() && m_eligibleVideoDevices.size(); }
     bool requiresDisplayCapture() const { return m_request.type == WebCore::MediaStreamRequest::Type::DisplayMedia && m_eligibleVideoDevices.size(); }
 
+    void setEligibleVideoDeviceUIDs(Vector<WebCore::CaptureDevice>&& devices) { m_eligibleVideoDevices = WTFMove(devices); }
+    void setEligibleAudioDeviceUIDs(Vector<WebCore::CaptureDevice>&& devices) { m_eligibleAudioDevices = WTFMove(devices); }
+
     Vector<String> videoDeviceUIDs() const;
     Vector<String> audioDeviceUIDs() const;
+    bool hasAudioDevice() const { return !m_eligibleAudioDevices.isEmpty(); }
+    bool hasVideoDevice() const { return !m_eligibleVideoDevices.isEmpty(); }
 
+    bool hasPersistentAccess() const { return m_hasPersistentAccess; }
+    void setHasPersistentAccess() { m_hasPersistentAccess = true; }
+
+    uint64_t userMediaID() const { return m_userMediaID; }
     uint64_t mainFrameID() const { return m_mainFrameID; }
     uint64_t frameID() const { return m_frameID; }
+
     WebCore::SecurityOrigin& topLevelDocumentSecurityOrigin() { return m_topLevelDocumentSecurityOrigin.get(); }
     WebCore::SecurityOrigin& userMediaDocumentSecurityOrigin() { return m_userMediaDocumentSecurityOrigin.get(); }
+    const WebCore::SecurityOrigin& topLevelDocumentSecurityOrigin() const { return m_topLevelDocumentSecurityOrigin.get(); }
+    const WebCore::SecurityOrigin& userMediaDocumentSecurityOrigin() const { return m_userMediaDocumentSecurityOrigin.get(); }
 
+    const WebCore::MediaStreamRequest& userRequest() const { return m_request; }
+
     WebCore::MediaStreamRequest::Type requestType() const { return m_request.type; }
 
+    void setDeviceIdentifierHashSalt(String&& salt) { m_deviceIdentifierHashSalt = WTFMove(salt); }
+    const String& deviceIdentifierHashSalt() const { return m_deviceIdentifierHashSalt; }
+
+    WebCore::CaptureDevice audioDevice() const { return m_eligibleAudioDevices.isEmpty() ? WebCore::CaptureDevice { } : m_eligibleAudioDevices[0]; }
+    WebCore::CaptureDevice videoDevice() const { return m_eligibleVideoDevices.isEmpty() ? WebCore::CaptureDevice { } : m_eligibleVideoDevices[0]; }
+
 private:
     UserMediaPermissionRequestProxy(UserMediaPermissionRequestManagerProxy&, uint64_t userMediaID, uint64_t mainFrameID, uint64_t frameID, Ref<WebCore::SecurityOrigin>&& userMediaDocumentOrigin, Ref<WebCore::SecurityOrigin>&& topLevelDocumentOrigin, Vector<WebCore::CaptureDevice>&& audioDevices, Vector<WebCore::CaptureDevice>&& videoDevices, WebCore::MediaStreamRequest&&);
 
@@ -75,6 +96,8 @@
     Vector<WebCore::CaptureDevice> m_eligibleVideoDevices;
     Vector<WebCore::CaptureDevice> m_eligibleAudioDevices;
     WebCore::MediaStreamRequest m_request;
+    bool m_hasPersistentAccess { false };
+    String m_deviceIdentifierHashSalt;
 };
 
 } // namespace WebKit

Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.cpp (241166 => 241167)


--- trunk/Source/WebKit/UIProcess/WebPageProxy.cpp	2019-02-07 23:37:23 UTC (rev 241166)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.cpp	2019-02-07 23:49:00 UTC (rev 241167)
@@ -7015,12 +7015,12 @@
 }
 #endif
 
-void WebPageProxy::requestUserMediaPermissionForFrame(uint64_t userMediaID, uint64_t frameID, const WebCore::SecurityOriginData&  userMediaDocumentOriginData, const WebCore::SecurityOriginData& topLevelDocumentOriginData, const WebCore::MediaStreamRequest& request)
+void WebPageProxy::requestUserMediaPermissionForFrame(uint64_t userMediaID, uint64_t frameID, const WebCore::SecurityOriginData&  userMediaDocumentOriginData, const WebCore::SecurityOriginData& topLevelDocumentOriginData, WebCore::MediaStreamRequest&& request)
 {
 #if ENABLE(MEDIA_STREAM)
     MESSAGE_CHECK(m_process, m_process->webFrame(frameID));
 
-    userMediaPermissionRequestManager().requestUserMediaPermissionForFrame(userMediaID, frameID, userMediaDocumentOriginData.securityOrigin(), topLevelDocumentOriginData.securityOrigin(), request);
+    userMediaPermissionRequestManager().requestUserMediaPermissionForFrame(userMediaID, frameID, userMediaDocumentOriginData.securityOrigin(), topLevelDocumentOriginData.securityOrigin(), WTFMove(request));
 #else
     UNUSED_PARAM(userMediaID);
     UNUSED_PARAM(frameID);

Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.h (241166 => 241167)


--- trunk/Source/WebKit/UIProcess/WebPageProxy.h	2019-02-07 23:37:23 UTC (rev 241166)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.h	2019-02-07 23:49:00 UTC (rev 241167)
@@ -1601,7 +1601,7 @@
 #if ENABLE(MEDIA_STREAM)
     UserMediaPermissionRequestManagerProxy& userMediaPermissionRequestManager();
 #endif
-    void requestUserMediaPermissionForFrame(uint64_t userMediaID, uint64_t frameID, const WebCore::SecurityOriginData& userMediaDocumentOriginIdentifier, const WebCore::SecurityOriginData& topLevelDocumentOriginIdentifier, const WebCore::MediaStreamRequest&);
+    void requestUserMediaPermissionForFrame(uint64_t userMediaID, uint64_t frameID, const WebCore::SecurityOriginData& userMediaDocumentOriginIdentifier, const WebCore::SecurityOriginData& topLevelDocumentOriginIdentifier, WebCore::MediaStreamRequest&&);
     void enumerateMediaDevicesForFrame(uint64_t userMediaID, uint64_t frameID, const WebCore::SecurityOriginData& userMediaDocumentOriginData, const WebCore::SecurityOriginData& topLevelDocumentOriginData);
     void beginMonitoringCaptureDevices();
 
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to