WebKit Bugzilla
Attachment 361457 Details for
Bug 194240
: Filter out Overconstrainederror.constraint when getUserMedia is not granted
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch for landing
bug-194240-20190207150953.patch (text/plain), 48.96 KB, created by
youenn fablet
on 2019-02-07 15:09:54 PST
(
hide
)
Description:
Patch for landing
Filename:
MIME Type:
Creator:
youenn fablet
Created:
2019-02-07 15:09:54 PST
Size:
48.96 KB
patch
obsolete
>Subversion Revision: 241123 >diff --git a/Source/WebKit/ChangeLog b/Source/WebKit/ChangeLog >index ee72a97a247f82ac50435e13dae092165efa0793..637de79c9aaf4e1fdcbc11996fa23247e3af8618 100644 >--- a/Source/WebKit/ChangeLog >+++ b/Source/WebKit/ChangeLog >@@ -1,3 +1,53 @@ >+2019-02-07 Youenn Fablet <youenn@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 Youenn Fablet <youenn@apple.com> > > Make to clear sources from UserMediaCaptureManagerProxy and UserMediaCaptureManager when no longer needed >diff --git a/Source/WebKit/UIProcess/UserMediaPermissionCheckProxy.cpp b/Source/WebKit/UIProcess/UserMediaPermissionCheckProxy.cpp >index 96513eb011b000de0371bf7d222508214f2da7df..304fa21c24a6668b315e03b94b1ddbf9d9ef72d7 100644 >--- a/Source/WebKit/UIProcess/UserMediaPermissionCheckProxy.cpp >+++ b/Source/WebKit/UIProcess/UserMediaPermissionCheckProxy.cpp >@@ -41,19 +41,24 @@ UserMediaPermissionCheckProxy::UserMediaPermissionCheckProxy(uint64_t frameID, C > { > } > >+UserMediaPermissionCheckProxy::~UserMediaPermissionCheckProxy() >+{ >+ invalidate(); >+} >+ > void UserMediaPermissionCheckProxy::setUserMediaAccessInfo(bool allowed) > { > ASSERT(m_completionHandler); >- if (!m_completionHandler) >- return; >- >- m_completionHandler(allowed); >- m_completionHandler = nullptr; >+ complete(allowed); > } > >-void UserMediaPermissionCheckProxy::invalidate() >+void UserMediaPermissionCheckProxy::complete(Optional<bool> allowed) > { >- m_completionHandler = nullptr; >+ if (!m_completionHandler) >+ return; >+ >+ auto completionHandler = WTFMove(m_completionHandler); >+ completionHandler(allowed); > } > > } // namespace WebKit >diff --git a/Source/WebKit/UIProcess/UserMediaPermissionCheckProxy.h b/Source/WebKit/UIProcess/UserMediaPermissionCheckProxy.h >index 6a089506cea388d1d4c3d6defda5fe0e0aee57c4..9e00bb9374bb56d92064440a6ac74a6a7cfeab1b 100644 >--- a/Source/WebKit/UIProcess/UserMediaPermissionCheckProxy.h >+++ b/Source/WebKit/UIProcess/UserMediaPermissionCheckProxy.h >@@ -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 @@ namespace WebKit { > 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 @@ public: > > 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 @@ public: > > 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; >diff --git a/Source/WebKit/UIProcess/UserMediaPermissionRequestManagerProxy.cpp b/Source/WebKit/UIProcess/UserMediaPermissionRequestManagerProxy.cpp >index 9fa3a50d960a42500ae4ec5bf47f5ac99047ce84..7b8c6141edc93fdb55d2c8b6cec7ae8e2dd527af 100644 >--- a/Source/WebKit/UIProcess/UserMediaPermissionRequestManagerProxy.cpp >+++ b/Source/WebKit/UIProcess/UserMediaPermissionRequestManagerProxy.cpp >@@ -75,8 +75,6 @@ void UserMediaPermissionRequestManagerProxy::invalidatePendingRequests() > request->invalidate(); > m_pendingUserMediaRequests.clear(); > >- for (auto& request : m_pendingDeviceRequests.values()) >- request->invalidate(); > m_pendingDeviceRequests.clear(); > } > >@@ -92,23 +90,18 @@ void UserMediaPermissionRequestManagerProxy::captureDevicesChanged() > 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()) >- return; >- >- if (m_grantedRequests.isEmpty() && !originHasPersistentAccess) >+ 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 @@ void UserMediaPermissionRequestManagerProxy::clearCachedState() > 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 @@ void UserMediaPermissionRequestManagerProxy::userMediaAccessWasGranted(uint64_t > 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 @@ bool UserMediaPermissionRequestManagerProxy::wasRequestDenied(uint64_t mainFrame > 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 @@ void UserMediaPermissionRequestManagerProxy::scheduleNextRejection() > } > > #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 @@ void UserMediaPermissionRequestManagerProxy::requestUserMediaPermissionForFrame( > 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 = getRequestAction(m_page.mainFrame()->frameID(), 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)); >- >- 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); > >+ RealtimeMediaSourceCenter::InvalidConstraintsHandler invalidHandler = [this, request = request.copyRef()](const String& invalidConstraint) { >+ if (!request->isPending()) > return; >- } >- } > >- if (m_page.preferences().mockCaptureDevicesEnabled() && !m_page.preferences().mockCaptureDevicesPromptEnabled()) { >- pendingRequest->allow(); >- return; >- } >- >- // If page navigated, there is no need to call the page client for authorization. >- auto* webFrame = m_page.process().webFrame(frameID); >- >- if (!webFrame || !SecurityOrigin::createFromString(m_page.pageLoadState().activeURL())->isSameSchemeHostPort(topLevelOrigin->securityOrigin())) { >- denyRequest(userMediaID, UserMediaPermissionRequestProxy::UserMediaAccessDenialReason::NoConstraints, emptyString()); >- return; >- } >+ if (!m_page.isValid()) >+ 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()); >- }; >+ processUserMediaPermissionInvalidRequest(request.get(), invalidConstraint); >+ }; > >- 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 validHandler = [this, request = request.copyRef()](Vector<CaptureDevice>&& audioDevices, Vector<CaptureDevice>&& videoDevices, String&& deviceIdentifierHashSalt) mutable { >+ if (!request->isPending()) >+ return; > >- auto pendingRequest = m_pendingDeviceRequests.take(requestID); >- if (!pendingRequest) >- return; >+ if (!m_page.isValid() || !m_page.mainFrame()) >+ return; > >- if (!m_page.isValid()) >- return; >+ processUserMediaPermissionValidRequest(WTFMove(request), WTFMove(audioDevices), WTFMove(videoDevices), WTFMove(deviceIdentifierHashSalt)); >+ }; > > 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 @@ void UserMediaPermissionRequestManagerProxy::requestUserMediaPermissionForFrame( > } > > #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 = getRequestAction(request); >+ 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 @@ bool UserMediaPermissionRequestManagerProxy::wasGrantedVideoOrAudioAccess(uint64 > > 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,19 +498,56 @@ void UserMediaPermissionRequestManagerProxy::enumerateMediaDevicesForFrame(uint6 > #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) >- return; >- auto pendingRequest = m_pendingDeviceRequests.take(requestID); >- if (!pendingRequest) >+ 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; > > if (!m_page.isValid()) >@@ -490,43 +555,13 @@ void UserMediaPermissionRequestManagerProxy::enumerateMediaDevicesForFrame(uint6 > > 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; >- >- 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()); >+ bool revealIdsAndLabels = originHasPersistentAccess || wasGrantedVideoOrAudioAccess(frameID, userMediaDocumentOrigin.get(), topLevelDocumentOrigin.get()); >+ >+ 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); >diff --git a/Source/WebKit/UIProcess/UserMediaPermissionRequestManagerProxy.h b/Source/WebKit/UIProcess/UserMediaPermissionRequestManagerProxy.h >index eacce6f92b65ffcc29be4d13788da81d91590558..a115c43867537ec8d53df5dfbe52e2ecd6915e1e 100644 >--- a/Source/WebKit/UIProcess/UserMediaPermissionRequestManagerProxy.h >+++ b/Source/WebKit/UIProcess/UserMediaPermissionRequestManagerProxy.h >@@ -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 @@ public: > > 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,27 +72,33 @@ private: > 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, > 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; > >diff --git a/Source/WebKit/UIProcess/UserMediaPermissionRequestProxy.h b/Source/WebKit/UIProcess/UserMediaPermissionRequestProxy.h >index ac805e788be2317e0a7aaeb718909cf45bca8908..067f80203f1a5fdd3238c8ae29d7dcaca1aea12d 100644 >--- a/Source/WebKit/UIProcess/UserMediaPermissionRequestProxy.h >+++ b/Source/WebKit/UIProcess/UserMediaPermissionRequestProxy.h >@@ -48,21 +48,42 @@ public: > 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 @@ private: > Vector<WebCore::CaptureDevice> m_eligibleVideoDevices; > Vector<WebCore::CaptureDevice> m_eligibleAudioDevices; > WebCore::MediaStreamRequest m_request; >+ bool m_hasPersistentAccess { false }; >+ String m_deviceIdentifierHashSalt; > }; > > } // namespace WebKit >diff --git a/Source/WebKit/UIProcess/WebPageProxy.cpp b/Source/WebKit/UIProcess/WebPageProxy.cpp >index f399f0ef01ee4e8e601ecfda2e1e5321c2c226d0..70a0970e8f987b8168744e2ac64e35ac1715278f 100644 >--- a/Source/WebKit/UIProcess/WebPageProxy.cpp >+++ b/Source/WebKit/UIProcess/WebPageProxy.cpp >@@ -7015,12 +7015,12 @@ UserMediaPermissionRequestManagerProxy& WebPageProxy::userMediaPermissionRequest > } > #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); >diff --git a/Source/WebKit/UIProcess/WebPageProxy.h b/Source/WebKit/UIProcess/WebPageProxy.h >index 7be91943890b75d0e28ca3701f5b467ec08747a2..7d2b35b6289ec750f9b82c275d5916b6e0ebfa44 100644 >--- a/Source/WebKit/UIProcess/WebPageProxy.h >+++ b/Source/WebKit/UIProcess/WebPageProxy.h >@@ -1597,7 +1597,7 @@ private: > #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(); > >diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog >index 92df95ad5352450f1faba39888407349772739db..58975ddb5e56a86fc400dc56bd48683ebf86e68d 100644 >--- a/LayoutTests/ChangeLog >+++ b/LayoutTests/ChangeLog >@@ -1,3 +1,13 @@ >+2019-02-07 Youenn Fablet <youenn@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 Zalan Bujtas <zalan@apple.com> > > [LFC][Out-of-flow] Use the containing block's padding width when computing min/max width. >diff --git a/LayoutTests/fast/mediastream/overconstrainederror-constraint-expected.txt b/LayoutTests/fast/mediastream/overconstrainederror-constraint-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..442b5ba746cba694fd08423c5601067e48041fde >--- /dev/null >+++ b/LayoutTests/fast/mediastream/overconstrainederror-constraint-expected.txt >@@ -0,0 +1,4 @@ >+ >+PASS Before grant >+PASS After grant >+ >diff --git a/LayoutTests/fast/mediastream/overconstrainederror-constraint.html b/LayoutTests/fast/mediastream/overconstrainederror-constraint.html >new file mode 100644 >index 0000000000000000000000000000000000000000..c176efcebe6aaaa150d5a2a1c78e9194504ddfd0 >--- /dev/null >+++ b/LayoutTests/fast/mediastream/overconstrainederror-constraint.html >@@ -0,0 +1,39 @@ >+<!doctype html> >+<html> >+ <head> >+ <meta charset="utf-8"> >+ <title>OverConstrainedError.constraint testing</title> >+ <script src="../../resources/testharness.js"></script> >+ <script src="../../resources/testharnessreport.js"></script> >+ </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>
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 194240
:
361196
|
361304
|
361417
|
361457
|
361689