Diff
Modified: trunk/LayoutTests/ChangeLog (217909 => 217910)
--- trunk/LayoutTests/ChangeLog 2017-06-07 22:39:06 UTC (rev 217909)
+++ trunk/LayoutTests/ChangeLog 2017-06-07 23:27:14 UTC (rev 217910)
@@ -1,3 +1,18 @@
+2017-06-07 Youenn Fablet <you...@apple.com>
+
+ getUserMedia is prompting too often
+ https://bugs.webkit.org/show_bug.cgi?id=172859
+ <rdar://problem/32589950>
+
+ Reviewed by Eric Carlson.
+
+ * fast/mediastream/getUserMedia-grant-persistency-expected.txt: Added.
+ * fast/mediastream/getUserMedia-grant-persistency-reload-expected.txt: Added.
+ * fast/mediastream/getUserMedia-grant-persistency-reload.html: Added.
+ * fast/mediastream/getUserMedia-grant-persistency.html: Added.
+ * http/tests/media/media-stream/get-user-media-prompt-expected.txt:
+ * http/tests/media/media-stream/get-user-media-prompt.html: Last gum does not need a prompt anymore.
+
2017-06-07 Daniel Bates <daba...@apple.com>
Fetching Blob URLs with XHR gives null content-type and content-length
Added: trunk/LayoutTests/fast/mediastream/getUserMedia-grant-persistency-expected.txt (0 => 217910)
--- trunk/LayoutTests/fast/mediastream/getUserMedia-grant-persistency-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/mediastream/getUserMedia-grant-persistency-expected.txt 2017-06-07 23:27:14 UTC (rev 217910)
@@ -0,0 +1,6 @@
+
+PASS Testing same page getUserMedia grant persistency
+PASS Testing same page getUserMedia grant persistency in case page capture is in muted state
+PASS Testing same page getUserMedia grant persistency after in page navigation
+FAIL Testing same page getUserMedia grant persistency with visibility assert_true: Resolving getUserMedia promise should wait for page to be visible expected true got false
+
Added: trunk/LayoutTests/fast/mediastream/getUserMedia-grant-persistency-reload-expected.txt (0 => 217910)
--- trunk/LayoutTests/fast/mediastream/getUserMedia-grant-persistency-reload-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/mediastream/getUserMedia-grant-persistency-reload-expected.txt 2017-06-07 23:27:14 UTC (rev 217910)
@@ -0,0 +1,2 @@
+In case of reload, getUserMedia should not be allowed based on previous getUserMedia calls but only according client logic
+PASS
Added: trunk/LayoutTests/fast/mediastream/getUserMedia-grant-persistency-reload.html (0 => 217910)
--- trunk/LayoutTests/fast/mediastream/getUserMedia-grant-persistency-reload.html (rev 0)
+++ trunk/LayoutTests/fast/mediastream/getUserMedia-grant-persistency-reload.html 2017-06-07 23:27:14 UTC (rev 217910)
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script>
+if (window.testRunner) {
+ testRunner.dumpAsText();
+ testRunner.waitUntilDone();
+}
+function test() {
+ if (window.localStorage.getItem("gum-after-reload") == null) {
+ window.localStorage.setItem("gum-after-reload", "true")
+ if (window.testRunner)
+ testRunner.setUserMediaPermission(true);
+ navigator.mediaDevices.getUserMedia({audio:true, video:true}).then(() => {
+ internals.forceReload(true);
+ });
+ } else {
+ window.localStorage.clear();
+ if (window.testRunner)
+ testRunner.setUserMediaPermission(false);
+ navigator.mediaDevices.getUserMedia({audio:true, video:true}).then(() => {i
+ result.innerHTML = "FAIL";
+ if (window.testRunner)
+ testRunner.notifyDone();
+ }, () => {
+ result.innerHTML = "PASS";
+ if (window.testRunner)
+ testRunner.notifyDone();
+ });
+ };
+}
+</script>
+</head>
+<body _onload_="setTimeout(test, 0);">
+ <div>In case of reload, getUserMedia should not be allowed based on previous getUserMedia calls but only according client logic</div>
+ <div id="result"></div>
+</body>
+</html>
+
+
Added: trunk/LayoutTests/fast/mediastream/getUserMedia-grant-persistency.html (0 => 217910)
--- trunk/LayoutTests/fast/mediastream/getUserMedia-grant-persistency.html (rev 0)
+++ trunk/LayoutTests/fast/mediastream/getUserMedia-grant-persistency.html 2017-06-07 23:27:14 UTC (rev 217910)
@@ -0,0 +1,88 @@
+<!DOCTYPE HTML>
+<html>
+ <head>
+ <script src=""
+ <script src=""
+ </head>
+ <body>
+ <div id="navigateToSamePage"></div>
+ <script>
+promise_test((test) => {
+ if (window.testRunner)
+ testRunner.setUserMediaPermission(true);
+ return navigator.mediaDevices.getUserMedia({audio:false, video:true}).then((stream) => {
+ if (window.testRunner)
+ testRunner.setUserMediaPermission(false);
+ return navigator.mediaDevices.getUserMedia({audio:false, video:true});
+ }).then(() => {
+ return navigator.mediaDevices.getUserMedia({audio:true, video:false}).then(assert_unreached, (e) => {
+ assert_equals(e.name, "NotAllowedError");
+ });
+ }).then(() => {
+ if (window.testRunner)
+ testRunner.setUserMediaPermission(true);
+ return navigator.mediaDevices.getUserMedia({audio:true, video:false});
+ }).then(() => {
+ if (window.testRunner)
+ testRunner.setUserMediaPermission(false);
+ return navigator.mediaDevices.getUserMedia({audio:true, video:true});
+ });
+}, "Testing same page getUserMedia grant persistency");
+
+promise_test((test) => {
+ if (window.testRunner)
+ testRunner.setUserMediaPermission(true);
+ return navigator.mediaDevices.getUserMedia({audio:true, video:true}).then((stream) => {
+ if (window.testRunner)
+ testRunner.setUserMediaPermission(false);
+ return navigator.mediaDevices.getUserMedia({audio:true, video:true});
+ }).then(() => {
+ if (window.internals)
+ internals.setPageMuted("capturedevices");
+ return navigator.mediaDevices.getUserMedia({audio:true, video:true});
+ }).then(() => {
+ if (!window.internals)
+ return;
+ assert_true(internals.pageMediaState().includes("HasActiveVideoCaptureDevice"), "Check active video");
+ assert_true(internals.pageMediaState().includes("HasActiveAudioCaptureDevice"), "Check active audio");
+ });
+}, "Testing same page getUserMedia grant persistency in case page capture is in muted state");
+
+promise_test((test) => {
+ if (window.testRunner)
+ testRunner.setUserMediaPermission(true);
+ return navigator.mediaDevices.getUserMedia({audio:false, video:true}).then((stream) => {
+ if (window.testRunner)
+ testRunner.setUserMediaPermission(false);
+ return navigator.mediaDevices.getUserMedia({audio:false, video:true});
+ }).then(() => {
+ window.location = "#navigateToSamePage";
+ }).then(() => {
+ return navigator.mediaDevices.getUserMedia({audio:false, video:true});
+ });
+}, "Testing same page getUserMedia grant persistency after in page navigation");
+
+promise_test((test) => {
+ var isPageVisible = true;
+ if (window.testRunner)
+ testRunner.setUserMediaPermission(true);
+ return navigator.mediaDevices.getUserMedia({audio:false, video:true}).then((stream) => {
+ if (window.testRunner)
+ testRunner.setUserMediaPermission(false);
+ isPageVisible = false;
+ if (window.internals)
+ internals.setPageVisibility(false);
+ setTimeout(() => {
+ isPageVisible = true;
+ if (window.internals)
+ internals.setPageVisibility(true);
+ }, 100);
+ return navigator.mediaDevices.getUserMedia({audio:false, video:true});
+ }).then(() => {
+ assert_true(isPageVisible, "Resolving getUserMedia promise should wait for page to be visible");
+ });
+}, "Testing same page getUserMedia grant persistency with visibility");
+
+ </script>
+ </body>
+</html>
Modified: trunk/LayoutTests/http/tests/media/media-stream/get-user-media-prompt-expected.txt (217909 => 217910)
--- trunk/LayoutTests/http/tests/media/media-stream/get-user-media-prompt-expected.txt 2017-06-07 22:39:06 UTC (rev 217909)
+++ trunk/LayoutTests/http/tests/media/media-stream/get-user-media-prompt-expected.txt 2017-06-07 23:27:14 UTC (rev 217910)
@@ -3,23 +3,23 @@
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-PASS numberOfTimesGetUserMediaHasBeenCalled() is 0
+PASS numberOfTimesGetUserMediaPromptHasBeenCalled() is 0
** Request an audio-only stream, the user should be prompted **
PASS navigator.mediaDevices.getUserMedia({audio:true}).then(gotStream1); did not throw exception.
-PASS numberOfTimesGetUserMediaHasBeenCalled() is 1
+PASS numberOfTimesGetUserMediaPromptHasBeenCalled() is 1
PASS stream.getAudioTracks().length is 1
PASS stream.getVideoTracks().length is 0
** Request a video-only stream, the user should be prompted **
PASS navigator.mediaDevices.getUserMedia({video:true}).then(gotStream2); did not throw exception.
-PASS numberOfTimesGetUserMediaHasBeenCalled() is 2
+PASS numberOfTimesGetUserMediaPromptHasBeenCalled() is 2
PASS stream.getAudioTracks().length is 0
PASS stream.getVideoTracks().length is 1
-** Request a stream with video and audio, the user should be prompted again **
+** Request a stream with video and audio, the user should not be prompted again **
PASS navigator.mediaDevices.getUserMedia({audio:true, video:true}).then(gotStream3); did not throw exception.
-PASS numberOfTimesGetUserMediaHasBeenCalled() is 3
+PASS numberOfTimesGetUserMediaPromptHasBeenCalled() is 2
PASS stream.getAudioTracks().length is 1
PASS stream.getVideoTracks().length is 1
Modified: trunk/LayoutTests/http/tests/media/media-stream/get-user-media-prompt.html (217909 => 217910)
--- trunk/LayoutTests/http/tests/media/media-stream/get-user-media-prompt.html 2017-06-07 22:39:06 UTC (rev 217909)
+++ trunk/LayoutTests/http/tests/media/media-stream/get-user-media-prompt.html 2017-06-07 23:27:14 UTC (rev 217910)
@@ -7,7 +7,7 @@
<script src=""
<script>
- function numberOfTimesGetUserMediaHasBeenCalled()
+ function numberOfTimesGetUserMediaPromptHasBeenCalled()
{
return testRunner.userMediaPermissionRequestCountForOrigin(document.location.href, document.location.href);
}
@@ -15,7 +15,7 @@
function gotStream3(s)
{
stream = s;
- shouldBe("numberOfTimesGetUserMediaHasBeenCalled()", "3");
+ shouldBe("numberOfTimesGetUserMediaPromptHasBeenCalled()", "2");
shouldBe("stream.getAudioTracks().length", "1");
shouldBe("stream.getVideoTracks().length", "1");
@@ -26,11 +26,11 @@
function gotStream2(s)
{
stream = s;
- shouldBe("numberOfTimesGetUserMediaHasBeenCalled()", "2");
+ shouldBe("numberOfTimesGetUserMediaPromptHasBeenCalled()", "2");
shouldBe("stream.getAudioTracks().length", "0");
shouldBe("stream.getVideoTracks().length", "1");
- debug("<br>** Request a stream with video and audio, the user should be prompted again **");
+ debug("<br>** Request a stream with video and audio, the user should not be prompted again **");
shouldNotThrow("navigator.mediaDevices.getUserMedia({audio:true, video:true}).then(gotStream3);");
}
@@ -37,7 +37,7 @@
function gotStream1(s)
{
stream = s;
- shouldBe("numberOfTimesGetUserMediaHasBeenCalled()", "1");
+ shouldBe("numberOfTimesGetUserMediaPromptHasBeenCalled()", "1");
shouldBe("stream.getAudioTracks().length", "1");
shouldBe("stream.getVideoTracks().length", "0");
@@ -50,7 +50,7 @@
description("Tests that user is only prompted once per device in the current browsing context.");
testRunner.resetUserMediaPermissionRequestCountForOrigin(document.location.href, document.location.href);
- shouldBe("numberOfTimesGetUserMediaHasBeenCalled()", "0");
+ shouldBe("numberOfTimesGetUserMediaPromptHasBeenCalled()", "0");
debug("<br>** Request an audio-only stream, the user should be prompted **");
shouldNotThrow("navigator.mediaDevices.getUserMedia({audio:true}).then(gotStream1);");
Modified: trunk/Source/WebCore/ChangeLog (217909 => 217910)
--- trunk/Source/WebCore/ChangeLog 2017-06-07 22:39:06 UTC (rev 217909)
+++ trunk/Source/WebCore/ChangeLog 2017-06-07 23:27:14 UTC (rev 217910)
@@ -1,3 +1,19 @@
+2017-06-07 Youenn Fablet <you...@apple.com>
+
+ getUserMedia is prompting too often
+ https://bugs.webkit.org/show_bug.cgi?id=172859
+ <rdar://problem/32589950>
+
+ Reviewed by Eric Carlson.
+
+ Tests: fast/mediastream/getUserMedia-grant-persistency-reload.html
+ fast/mediastream/getUserMedia-grant-persistency.html
+
+ * loader/FrameLoaderClient.h:
+ * page/Frame.cpp:
+ (WebCore::Frame::setDocument): Allows notifying of change of main frame document.
+ UIProcess will use that to remove unneeded previously granted gum permission.
+
2017-06-07 Chris Dumez <cdu...@apple.com>
Align <col span>/<colgroup span> limits with the latest HTML specification
Modified: trunk/Source/WebCore/loader/FrameLoaderClient.h (217909 => 217910)
--- trunk/Source/WebCore/loader/FrameLoaderClient.h 2017-06-07 22:39:06 UTC (rev 217909)
+++ trunk/Source/WebCore/loader/FrameLoaderClient.h 2017-06-07 23:27:14 UTC (rev 217910)
@@ -152,6 +152,7 @@
virtual void dispatchDidChangeProvisionalURL() { }
virtual void dispatchDidCancelClientRedirect() = 0;
virtual void dispatchWillPerformClientRedirect(const URL&, double interval, double fireDate) = 0;
+ virtual void dispatchDidChangeMainDocument() { }
virtual void dispatchDidNavigateWithinPage() { }
virtual void dispatchDidChangeLocationWithinPage() = 0;
virtual void dispatchDidPushStateWithinPage() = 0;
Modified: trunk/Source/WebCore/page/Frame.cpp (217909 => 217910)
--- trunk/Source/WebCore/page/Frame.cpp 2017-06-07 22:39:06 UTC (rev 217909)
+++ trunk/Source/WebCore/page/Frame.cpp 2017-06-07 23:27:14 UTC (rev 217910)
@@ -271,7 +271,10 @@
return;
m_documentIsBeingReplaced = true;
-
+
+ if (isMainFrame())
+ m_loader.client().dispatchDidChangeMainDocument();
+
if (m_doc && m_doc->pageCacheState() != Document::InPageCache)
m_doc->prepareForDestruction();
Modified: trunk/Source/WebKit2/ChangeLog (217909 => 217910)
--- trunk/Source/WebKit2/ChangeLog 2017-06-07 22:39:06 UTC (rev 217909)
+++ trunk/Source/WebKit2/ChangeLog 2017-06-07 23:27:14 UTC (rev 217910)
@@ -1,3 +1,44 @@
+2017-06-07 Youenn Fablet <you...@apple.com>
+
+ getUserMedia is prompting too often
+ https://bugs.webkit.org/show_bug.cgi?id=172859
+ <rdar://problem/32589950>
+
+ Reviewed by Eric Carlson.
+
+ Introduce a storage of granted requests to skip prompting when needed.
+ This is a partial implementation as granted requests should not happen for background tabs.
+ This will be covered in a follow-up patch.
+ Covered by manual tests.
+
+ A granted request keeps its mainFrameID.
+ Whenever the document of the main frame changes, the granted requests for that mainFrameID will be removed.
+ This handles the case of navigating, reloading... while still supporting the case of granting getUserMedia after in page navigation.
+
+ * UIProcess/UserMediaPermissionRequestManagerProxy.cpp:
+ (WebKit::UserMediaPermissionRequestManagerProxy::createRequest):
+ (WebKit::UserMediaPermissionRequestManagerProxy::userMediaAccessWasGranted):
+ (WebKit::UserMediaPermissionRequestManagerProxy::removeGrantedAccess):
+ (WebKit::UserMediaPermissionRequestManagerProxy::searchForGrantedRequest):
+ (WebKit::UserMediaPermissionRequestManagerProxy::grantAccess):
+ (WebKit::UserMediaPermissionRequestManagerProxy::requestUserMediaPermissionForFrame):
+ * UIProcess/UserMediaPermissionRequestManagerProxy.h:
+ * UIProcess/UserMediaPermissionRequestProxy.cpp:
+ (WebKit::UserMediaPermissionRequestProxy::UserMediaPermissionRequestProxy):
+ * UIProcess/UserMediaPermissionRequestProxy.h:
+ (WebKit::UserMediaPermissionRequestProxy::create):
+ (WebKit::UserMediaPermissionRequestProxy::mainFrameID):
+ (WebKit::UserMediaPermissionRequestProxy::frameID):
+ (WebKit::UserMediaPermissionRequestProxy::userMediaDocumentSecurityOrigin):
+ * UIProcess/WebPageProxy.cpp:
+ (WebKit::WebPageProxy::didChangeMainDocument):
+ (WebKit::WebPageProxy::backForwardGoToItem):
+ * UIProcess/WebPageProxy.h:
+ * UIProcess/WebPageProxy.messages.in:
+ * WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp:
+ (WebKit::WebFrameLoaderClient::dispatchDidChangeMainDocument):
+ * WebProcess/WebCoreSupport/WebFrameLoaderClient.h:
+
2017-06-07 Dan Bernstein <m...@apple.com>
[Cocoa] additionalReadAccessAllowedURLs should be consumed before loading the injected bundle
Modified: trunk/Source/WebKit2/UIProcess/UserMediaPermissionRequestManagerProxy.cpp (217909 => 217910)
--- trunk/Source/WebKit2/UIProcess/UserMediaPermissionRequestManagerProxy.cpp 2017-06-07 22:39:06 UTC (rev 217909)
+++ trunk/Source/WebKit2/UIProcess/UserMediaPermissionRequestManagerProxy.cpp 2017-06-07 23:27:14 UTC (rev 217910)
@@ -79,9 +79,9 @@
invalidatePendingRequests();
}
-Ref<UserMediaPermissionRequestProxy> UserMediaPermissionRequestManagerProxy::createRequest(uint64_t userMediaID, uint64_t frameID, Ref<WebCore::SecurityOrigin>&& userMediaDocumentOrigin, Ref<WebCore::SecurityOrigin>&& topLevelDocumentOrigin, Vector<String>&& audioDeviceUIDs, Vector<String>&& videoDeviceUIDs, String&& deviceIDHashSalt)
+Ref<UserMediaPermissionRequestProxy> UserMediaPermissionRequestManagerProxy::createRequest(uint64_t userMediaID, uint64_t mainFrameID, uint64_t frameID, Ref<WebCore::SecurityOrigin>&& userMediaDocumentOrigin, Ref<WebCore::SecurityOrigin>&& topLevelDocumentOrigin, Vector<String>&& audioDeviceUIDs, Vector<String>&& videoDeviceUIDs, String&& deviceIDHashSalt)
{
- auto request = UserMediaPermissionRequestProxy::create(*this, userMediaID, frameID, WTFMove(userMediaDocumentOrigin), WTFMove(topLevelDocumentOrigin), WTFMove(audioDeviceUIDs), WTFMove(videoDeviceUIDs), WTFMove(deviceIDHashSalt));
+ auto request = UserMediaPermissionRequestProxy::create(*this, userMediaID, mainFrameID, frameID, WTFMove(userMediaDocumentOrigin), WTFMove(topLevelDocumentOrigin), WTFMove(audioDeviceUIDs), WTFMove(videoDeviceUIDs), WTFMove(deviceIDHashSalt));
m_pendingUserMediaRequests.add(userMediaID, request.ptr());
return request;
}
@@ -154,8 +154,8 @@
if (!request)
return;
- UserMediaProcessManager::singleton().willCreateMediaStream(*this, !audioDeviceUID.isEmpty(), !videoDeviceUID.isEmpty());
- m_page.process().send(Messages::WebPage::UserMediaAccessWasGranted(userMediaID, audioDeviceUID, videoDeviceUID, request->deviceIdentifierHashSalt()), m_page.pageID());
+ grantAccess(userMediaID, audioDeviceUID, videoDeviceUID, request->deviceIdentifierHashSalt());
+ m_grantedRequests.append(request.releaseNonNull());
#else
UNUSED_PARAM(userMediaID);
UNUSED_PARAM(audioDeviceUID);
@@ -163,6 +163,47 @@
#endif
}
+#if ENABLE(MEDIA_STREAM)
+void UserMediaPermissionRequestManagerProxy::removeGrantedAccess(uint64_t frameID)
+{
+ m_grantedRequests.removeAllMatching([frameID](const auto& grantedRequest) {
+ return grantedRequest->mainFrameID() == frameID;
+ });
+}
+
+const UserMediaPermissionRequestProxy* UserMediaPermissionRequestManagerProxy::searchForGrantedRequest(uint64_t frameID, const WebCore::SecurityOrigin& userMediaDocumentOrigin, const WebCore::SecurityOrigin& topLevelDocumentOrigin, bool needsAudio, bool needsVideo) const
+{
+ bool checkForAudio = needsAudio;
+ bool checkForVideo = needsVideo;
+ for (const auto& grantedRequest : m_grantedRequests) {
+ if (!grantedRequest->userMediaDocumentSecurityOrigin().isSameSchemeHostPort(userMediaDocumentOrigin))
+ continue;
+ if (!grantedRequest->topLevelDocumentSecurityOrigin().isSameSchemeHostPort(topLevelDocumentOrigin))
+ continue;
+ if (grantedRequest->frameID() != frameID)
+ continue;
+
+ if (!grantedRequest->videoDeviceUIDs().isEmpty())
+ checkForVideo = false;
+
+ if (!grantedRequest->audioDeviceUIDs().isEmpty())
+ checkForAudio = false;
+
+ if (checkForVideo || checkForAudio)
+ continue;
+
+ return grantedRequest.ptr();
+ }
+ return nullptr;
+}
+
+void UserMediaPermissionRequestManagerProxy::grantAccess(uint64_t userMediaID, const String& audioDeviceUID, const String& videoDeviceUID, const String& deviceIdentifierHashSalt)
+{
+ UserMediaProcessManager::singleton().willCreateMediaStream(*this, !audioDeviceUID.isEmpty(), !videoDeviceUID.isEmpty());
+ m_page.process().send(Messages::WebPage::UserMediaAccessWasGranted(userMediaID, audioDeviceUID, videoDeviceUID, deviceIdentifierHashSalt), m_page.pageID());
+}
+#endif
+
void UserMediaPermissionRequestManagerProxy::rejectionTimerFired()
{
uint64_t userMediaID = m_pendingRejections[0];
@@ -197,7 +238,7 @@
};
WebCore::RealtimeMediaSourceCenter::ValidConstraintsHandler validHandler = [this, userMediaID, frameID, userMediaDocumentOrigin = userMediaDocumentOrigin.copyRef(), topLevelDocumentOrigin = topLevelDocumentOrigin.copyRef()](Vector<String>&& audioDeviceUIDs, Vector<String>&& videoDeviceUIDs, String&& deviceIdentifierHashSalt) mutable {
- if (!m_page.isValid())
+ if (!m_page.isValid() || !m_page.mainFrame())
return;
if (videoDeviceUIDs.isEmpty() && audioDeviceUIDs.isEmpty()) {
@@ -205,10 +246,18 @@
return;
}
+ auto* grantedRequest = searchForGrantedRequest(frameID, userMediaDocumentOrigin.get(), topLevelDocumentOrigin.get(), !audioDeviceUIDs.isEmpty(), !videoDeviceUIDs.isEmpty());
+ if (grantedRequest) {
+ // 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.
+ grantAccess(userMediaID, audioDeviceUIDs.isEmpty() ? String() : audioDeviceUIDs[0], videoDeviceUIDs.isEmpty() ? String() : videoDeviceUIDs[0], grantedRequest->deviceIdentifierHashSalt());
+ return;
+ }
auto userMediaOrigin = API::SecurityOrigin::create(userMediaDocumentOrigin.get());
auto topLevelOrigin = API::SecurityOrigin::create(topLevelDocumentOrigin.get());
- auto request = createRequest(userMediaID, frameID, WTFMove(userMediaDocumentOrigin), WTFMove(topLevelDocumentOrigin), WTFMove(audioDeviceUIDs), WTFMove(videoDeviceUIDs), WTFMove(deviceIdentifierHashSalt));
+ auto request = createRequest(userMediaID, m_page.mainFrame()->frameID(), frameID, WTFMove(userMediaDocumentOrigin), WTFMove(topLevelDocumentOrigin), WTFMove(audioDeviceUIDs), WTFMove(videoDeviceUIDs), WTFMove(deviceIdentifierHashSalt));
+
if (m_page.preferences().mockCaptureDevicesEnabled() && !m_page.preferences().mockCaptureDevicesPromptEnabled()) {
// FIXME: https://bugs.webkit.org/show_bug.cgi?id=172989
// We should probably only allow this if page is already actively capturing or page is visible.
Modified: trunk/Source/WebKit2/UIProcess/UserMediaPermissionRequestManagerProxy.h (217909 => 217910)
--- trunk/Source/WebKit2/UIProcess/UserMediaPermissionRequestManagerProxy.h 2017-06-07 22:39:06 UTC (rev 217909)
+++ trunk/Source/WebKit2/UIProcess/UserMediaPermissionRequestManagerProxy.h 2017-06-07 23:27:14 UTC (rev 217910)
@@ -47,6 +47,8 @@
void requestUserMediaPermissionForFrame(uint64_t userMediaID, uint64_t frameID, Ref<WebCore::SecurityOrigin>&& userMediaDocumentOrigin, Ref<WebCore::SecurityOrigin>&& topLevelDocumentOrigin, const WebCore::MediaConstraints& audioConstraints, const WebCore::MediaConstraints& videoConstraints);
+ void removeGrantedAccess(uint64_t mainFrameID);
+
void userMediaAccessWasGranted(uint64_t, const String& audioDeviceUID, const String& videoDeviceUID);
void userMediaAccessWasDenied(uint64_t, UserMediaPermissionRequestProxy::UserMediaAccessDenialReason);
@@ -61,9 +63,13 @@
void endedCaptureSession();
private:
- Ref<UserMediaPermissionRequestProxy> createRequest(uint64_t userMediaID, uint64_t frameID, Ref<WebCore::SecurityOrigin>&& userMediaDocumentOrigin, Ref<WebCore::SecurityOrigin>&& topLevelDocumentOrigin, Vector<String>&& audioDeviceUIDs, Vector<String>&& videoDeviceUIDs, String&&);
+ Ref<UserMediaPermissionRequestProxy> createRequest(uint64_t userMediaID, uint64_t mainFrameID, uint64_t frameID, Ref<WebCore::SecurityOrigin>&& userMediaDocumentOrigin, Ref<WebCore::SecurityOrigin>&& topLevelDocumentOrigin, Vector<String>&& audioDeviceUIDs, Vector<String>&& videoDeviceUIDs, String&&);
void denyRequest(uint64_t userMediaID, UserMediaPermissionRequestProxy::UserMediaAccessDenialReason, const String& invalidConstraint);
+#if ENABLE(MEDIA_STREAM)
+ void grantAccess(uint64_t userMediaID, const String& audioDeviceUID, const String& videoDeviceUID, const String& deviceIdentifierHashSalt);
+ const UserMediaPermissionRequestProxy* searchForGrantedRequest(uint64_t frameID, const WebCore::SecurityOrigin& userMediaDocumentOrigin, const WebCore::SecurityOrigin& topLevelDocumentOrigin, bool needsAudio, bool needsVideo) const;
+#endif
void getUserMediaPermissionInfo(uint64_t userMediaID, uint64_t frameID, UserMediaPermissionCheckProxy::CompletionHandler&&, Ref<WebCore::SecurityOrigin>&& userMediaDocumentOrigin, Ref<WebCore::SecurityOrigin>&& topLevelDocumentOrigin);
void syncWithWebCorePrefs() const;
@@ -75,6 +81,8 @@
WebCore::Timer m_rejectionTimer;
Vector<uint64_t> m_pendingRejections;
+
+ Vector<Ref<UserMediaPermissionRequestProxy>> m_grantedRequests;
};
} // namespace WebKit
Modified: trunk/Source/WebKit2/UIProcess/UserMediaPermissionRequestProxy.cpp (217909 => 217910)
--- trunk/Source/WebKit2/UIProcess/UserMediaPermissionRequestProxy.cpp 2017-06-07 22:39:06 UTC (rev 217909)
+++ trunk/Source/WebKit2/UIProcess/UserMediaPermissionRequestProxy.cpp 2017-06-07 23:27:14 UTC (rev 217910)
@@ -30,9 +30,10 @@
namespace WebKit {
-UserMediaPermissionRequestProxy::UserMediaPermissionRequestProxy(UserMediaPermissionRequestManagerProxy& manager, uint64_t userMediaID, uint64_t frameID, Ref<WebCore::SecurityOrigin>&& userMediaDocumentOrigin, Ref<WebCore::SecurityOrigin>&& topLevelDocumentOrigin, Vector<String>&& audioDeviceUIDs, Vector<String>&& videoDeviceUIDs, String&& deviceIDHashSalt)
+UserMediaPermissionRequestProxy::UserMediaPermissionRequestProxy(UserMediaPermissionRequestManagerProxy& manager, uint64_t userMediaID, uint64_t mainFrameID, uint64_t frameID, Ref<WebCore::SecurityOrigin>&& userMediaDocumentOrigin, Ref<WebCore::SecurityOrigin>&& topLevelDocumentOrigin, Vector<String>&& audioDeviceUIDs, Vector<String>&& videoDeviceUIDs, String&& deviceIDHashSalt)
: m_manager(&manager)
, m_userMediaID(userMediaID)
+ , m_mainFrameID(mainFrameID)
, m_frameID(frameID)
, m_userMediaDocumentSecurityOrigin(WTFMove(userMediaDocumentOrigin))
, m_topLevelDocumentSecurityOrigin(WTFMove(topLevelDocumentOrigin))
Modified: trunk/Source/WebKit2/UIProcess/UserMediaPermissionRequestProxy.h (217909 => 217910)
--- trunk/Source/WebKit2/UIProcess/UserMediaPermissionRequestProxy.h 2017-06-07 22:39:06 UTC (rev 217909)
+++ trunk/Source/WebKit2/UIProcess/UserMediaPermissionRequestProxy.h 2017-06-07 23:27:14 UTC (rev 217910)
@@ -33,9 +33,9 @@
class UserMediaPermissionRequestProxy : public API::ObjectImpl<API::Object::Type::UserMediaPermissionRequest> {
public:
- static Ref<UserMediaPermissionRequestProxy> create(UserMediaPermissionRequestManagerProxy& manager, uint64_t userMediaID, uint64_t frameID, Ref<WebCore::SecurityOrigin>&& userMediaDocumentOrigin, Ref<WebCore::SecurityOrigin>&& topLevelDocumentOrigin, Vector<String>&& videoDeviceUIDs, Vector<String>&& audioDeviceUIDs, String&& deviceIDHashSalt)
+ static Ref<UserMediaPermissionRequestProxy> create(UserMediaPermissionRequestManagerProxy& manager, uint64_t userMediaID, uint64_t mainFrameID, uint64_t frameID, Ref<WebCore::SecurityOrigin>&& userMediaDocumentOrigin, Ref<WebCore::SecurityOrigin>&& topLevelDocumentOrigin, Vector<String>&& videoDeviceUIDs, Vector<String>&& audioDeviceUIDs, String&& deviceIDHashSalt)
{
- return adoptRef(*new UserMediaPermissionRequestProxy(manager, userMediaID, frameID, WTFMove(userMediaDocumentOrigin), WTFMove(topLevelDocumentOrigin), WTFMove(videoDeviceUIDs), WTFMove(audioDeviceUIDs), WTFMove(deviceIDHashSalt)));
+ return adoptRef(*new UserMediaPermissionRequestProxy(manager, userMediaID, mainFrameID, frameID, WTFMove(userMediaDocumentOrigin), WTFMove(topLevelDocumentOrigin), WTFMove(videoDeviceUIDs), WTFMove(audioDeviceUIDs), WTFMove(deviceIDHashSalt)));
}
void allow(const String& videoDeviceUID, const String& audioDeviceUID);
@@ -51,17 +51,19 @@
const Vector<String>& videoDeviceUIDs() const { return m_videoDeviceUIDs; }
const Vector<String>& audioDeviceUIDs() const { return m_audioDeviceUIDs; }
+ 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(); }
- WebCore::SecurityOrigin& topLevelDocumentSecurityOrigin() { return m_topLevelDocumentSecurityOrigin.get(); }
const String& deviceIdentifierHashSalt() const { return m_deviceIdentifierHashSalt; }
private:
- UserMediaPermissionRequestProxy(UserMediaPermissionRequestManagerProxy&, uint64_t userMediaID, uint64_t frameID, Ref<WebCore::SecurityOrigin>&& userMediaDocumentOrigin, Ref<WebCore::SecurityOrigin>&& topLevelDocumentOrigin, Vector<String>&& videoDeviceUIDs, Vector<String>&& audioDeviceUIDs, String&&);
+ UserMediaPermissionRequestProxy(UserMediaPermissionRequestManagerProxy&, uint64_t userMediaID, uint64_t mainFrameID, uint64_t frameID, Ref<WebCore::SecurityOrigin>&& userMediaDocumentOrigin, Ref<WebCore::SecurityOrigin>&& topLevelDocumentOrigin, Vector<String>&& videoDeviceUIDs, Vector<String>&& audioDeviceUIDs, String&&);
UserMediaPermissionRequestManagerProxy* m_manager;
uint64_t m_userMediaID;
+ uint64_t m_mainFrameID;
uint64_t m_frameID;
Ref<WebCore::SecurityOrigin> m_userMediaDocumentSecurityOrigin;
Ref<WebCore::SecurityOrigin> m_topLevelDocumentSecurityOrigin;
Modified: trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp (217909 => 217910)
--- trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp 2017-06-07 22:39:06 UTC (rev 217909)
+++ trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp 2017-06-07 23:27:14 UTC (rev 217910)
@@ -3522,6 +3522,15 @@
m_pageClient.didSameDocumentNavigationForMainFrame(navigationType);
}
+void WebPageProxy::didChangeMainDocument(uint64_t frameID)
+{
+#if ENABLE(MEDIA_STREAM)
+ userMediaPermissionRequestManager().removeGrantedAccess(frameID);
+#else
+ UNUSED_PARAM(frameID);
+#endif
+}
+
void WebPageProxy::didReceiveTitleForFrame(uint64_t frameID, const String& title, const UserData& userData)
{
PageClientProtector protector(m_pageClient);
Modified: trunk/Source/WebKit2/UIProcess/WebPageProxy.h (217909 => 217910)
--- trunk/Source/WebKit2/UIProcess/WebPageProxy.h 2017-06-07 22:39:06 UTC (rev 217909)
+++ trunk/Source/WebKit2/UIProcess/WebPageProxy.h 2017-06-07 23:27:14 UTC (rev 217910)
@@ -1245,6 +1245,8 @@
void didFinishLoadForFrame(uint64_t frameID, uint64_t navigationID, const UserData&);
void didFailLoadForFrame(uint64_t frameID, uint64_t navigationID, const WebCore::ResourceError&, const UserData&);
void didSameDocumentNavigationForFrame(uint64_t frameID, uint64_t navigationID, uint32_t sameDocumentNavigationType, const String&, const UserData&);
+ void didChangeMainDocument(uint64_t frameID);
+
void didReceiveTitleForFrame(uint64_t frameID, const String&, const UserData&);
void didFirstLayoutForFrame(uint64_t frameID, const UserData&);
void didFirstVisuallyNonEmptyLayoutForFrame(uint64_t frameID, const UserData&);
Modified: trunk/Source/WebKit2/UIProcess/WebPageProxy.messages.in (217909 => 217910)
--- trunk/Source/WebKit2/UIProcess/WebPageProxy.messages.in 2017-06-07 22:39:06 UTC (rev 217909)
+++ trunk/Source/WebKit2/UIProcess/WebPageProxy.messages.in 2017-06-07 23:27:14 UTC (rev 217910)
@@ -133,6 +133,7 @@
DidRunInsecureContentForFrame(uint64_t frameID, WebKit::UserData userData)
DidDetectXSSForFrame(uint64_t frameID, WebKit::UserData userData)
DidSameDocumentNavigationForFrame(uint64_t frameID, uint64_t navigationID, uint32_t type, String url, WebKit::UserData userData)
+ DidChangeMainDocument(uint64_t frameID);
DidDestroyNavigation(uint64_t navigationID)
HasInsecureContent() -> (enum WebCore::HasInsecureContent hasInsecureContent)
Modified: trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp (217909 => 217910)
--- trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp 2017-06-07 22:39:06 UTC (rev 217909)
+++ trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp 2017-06-07 23:27:14 UTC (rev 217910)
@@ -336,6 +336,15 @@
webPage->send(Messages::WebPageProxy::DidSameDocumentNavigationForFrame(m_frame->frameID(), navigationID, SameDocumentNavigationAnchorNavigation, m_frame->coreFrame()->document()->url().string(), UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get())));
}
+void WebFrameLoaderClient::dispatchDidChangeMainDocument()
+{
+ WebPage* webPage = m_frame->page();
+ if (!webPage)
+ return;
+
+ webPage->send(Messages::WebPageProxy::DidChangeMainDocument(m_frame->frameID()));
+}
+
void WebFrameLoaderClient::dispatchDidPushStateWithinPage()
{
WebPage* webPage = m_frame->page();
Modified: trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebFrameLoaderClient.h (217909 => 217910)
--- trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebFrameLoaderClient.h 2017-06-07 22:39:06 UTC (rev 217909)
+++ trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebFrameLoaderClient.h 2017-06-07 23:27:14 UTC (rev 217910)
@@ -84,7 +84,8 @@
#if ENABLE(DATA_DETECTION)
void dispatchDidFinishDataDetection(NSArray *detectionResults) final;
#endif
-
+ void dispatchDidChangeMainDocument() final;
+
void dispatchDidDispatchOnloadEvents() final;
void dispatchDidReceiveServerRedirectForProvisionalLoad() final;
void dispatchDidChangeProvisionalURL() final;