[MediaStream] MediaDeviceInfo deviceId and groupId must be unique to the page's origin
authoreric.carlson@apple.com <eric.carlson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 25 Feb 2016 15:18:21 +0000 (15:18 +0000)
committereric.carlson@apple.com <eric.carlson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 25 Feb 2016 15:18:21 +0000 (15:18 +0000)
https://bugs.webkit.org/show_bug.cgi?id=153163
<rdar://problem/24334526>

Reviewed by Tim Horton.

Source/WebCore:

Tests: http/tests/media/media-stream/enumerate-devices-source-id-persistent.html
       http/tests/media/media-stream/enumerate-devices-source-id.html

* Modules/mediastream/MediaDevicesRequest.cpp:
(WebCore::MediaDevicesRequest::start): Don't check document.hasHadActiveMediaStreamTrack, do it
  in didCompleteTrackSourceInfoRequest where we need the information.
(WebCore::MediaDevicesRequest::didCompletePermissionCheck): Renamed from didCompleteCheck, save
  device ID hash string.
(WebCore::hashString): Hash a string with SHA1.
(WebCore::MediaDevicesRequest::hashID): Hash and ID.
(WebCore::MediaDevicesRequest::didCompleteTrackSourceInfoRequest): Hash deviceId and groupId.
(WebCore::MediaDevicesRequest::didCompleteCheck): Deleted.
(WebCore::MediaDevicesRequest::getTrackSources): Deleted.
(WebCore::MediaDevicesRequest::didCompleteRequest): Deleted.
* Modules/mediastream/MediaDevicesRequest.h:

* Modules/mediastream/UserMediaPermissionCheck.cpp:
(WebCore::UserMediaPermissionCheck::userMediaDocumentOrigin): Renamed from securityOrigin.
(WebCore::UserMediaPermissionCheck::topLevelDocumentOrigin): New, return the top level document origin.
(WebCore::UserMediaPermissionCheck::setUserMediaAccessInfo): Renamed from setHasPersistentPermission.
(WebCore::UserMediaPermissionCheck::securityOrigin): Deleted.
(WebCore::UserMediaPermissionCheck::setHasPersistentPermission): Deleted.
* Modules/mediastream/UserMediaPermissionCheck.h:

* Modules/mediastream/UserMediaRequest.cpp:
(WebCore::UserMediaRequest::userMediaDocumentOrigin): Renamed from securityOrigin.
(WebCore::UserMediaRequest::topLevelDocumentOrigin): New, return the top level document origin.
(WebCore::UserMediaRequest::securityOrigin): Deleted.
* Modules/mediastream/UserMediaRequest.h:
(WebCore::UserMediaRequest::requiresAudio): Deleted, unused.
(WebCore::UserMediaRequest::requiresVideo): Ditto.

* html/HTMLMediaElement.cpp:
(WebCore::HTMLMediaElement::mediaPlayerMediaDeviceIdentifierStorageDirectory): Deleted, unused.
* html/HTMLMediaElement.h:

* platform/graphics/MediaPlayer.h:
(WebCore::MediaPlayerClient::mediaPlayerMediaDeviceIdentifierStorageDirectory): Deleted.

* platform/mediastream/MediaStreamTrackSourcesRequestClient.h:
(WebCore::MediaStreamTrackSourcesRequestClient::didCompleteTrackSourceInfoRequest): Renamed from didCompleteRequest.

* platform/mediastream/mac/RealtimeMediaSourceCenterMac.cpp:
(WebCore::RealtimeMediaSourceCenterMac::getMediaStreamTrackSources): Ditto.

* platform/mock/MockRealtimeMediaSourceCenter.cpp:
(WebCore::MockRealtimeMediaSourceCenter::getMediaStreamTrackSources): Ditto.

Source/WebKit/mac:

* WebCoreSupport/WebUserMediaClient.mm:
(WebUserMediaClient::requestUserMediaAccess):
(WebUserMediaClient::checkUserMediaPermission):
(-[WebUserMediaPolicyCheckerListener allow]):
(-[WebUserMediaPolicyCheckerListener deny]):

Source/WebKit2:

* CMakeLists.txt: Add WKFrameHandleRef.cpp.

* Shared/API/c/WKBase.h: Add WKFrameHandleRef.
* UIProcess/API/APIUIClient.h:
(API::UIClient::decidePolicyForUserMediaPermissionRequest): Add parameter top level document
  security context.
(API::UIClient::checkUserMediaPermissionForOrigin): Ditto.

* UIProcess/API/C/WKAPICast.h: Add FrameHandle.

* UIProcess/API/C/WKFrameHandleRef.cpp: Added.
* UIProcess/API/C/WKFrameHandleRef.h: Added.

* UIProcess/API/C/WKFrameInfoRef.cpp:
(WKFrameInfoGetFrameHandleRef): Added.
* UIProcess/API/C/WKFrameInfoRef.h:

* UIProcess/API/C/WKPage.cpp:
(WKPageSetPageUIClient): Add parameters to decidePolicyForUserMediaPermissionRequest and
  checkUserMediaPermissionForOrigin for top level document security context.

* UIProcess/API/C/WKPageUIClient.h: Ditto.

* UIProcess/API/C/WKUserMediaPermissionCheck.cpp:
(WKUserMediaPermissionCheckSetUserMediaAccessInfo): Renamed from WKUserMediaPermissionCheckSetHasPersistentPermission,
  add parameter for top level document security context.
(WKUserMediaPermissionCheckSetHasPersistentPermission): Deleted.
* UIProcess/API/C/WKUserMediaPermissionCheck.h:

* UIProcess/API/gtk/WebKitUserMediaPermissionRequest.cpp:
(webkitUserMediaPermissionRequestCreate): Add top level document origin.

* UIProcess/UserMediaPermissionCheckProxy.cpp:
(WebKit::UserMediaPermissionCheckProxy::setUserMediaAccessInfo): Renamed from setHasPersistentPermission.
(WebKit::UserMediaPermissionCheckProxy::setHasPersistentPermission): Deleted.
* UIProcess/UserMediaPermissionCheckProxy.h:

* UIProcess/UserMediaPermissionRequestManagerProxy.cpp:
(WebKit::UserMediaPermissionRequestManagerProxy::didCompleteUserMediaPermissionCheck): Add parameter
 for device id hash salt.
* UIProcess/UserMediaPermissionRequestManagerProxy.h:

* UIProcess/UserMediaPermissionRequestProxy.h:
(WebKit::UserMediaPermissionRequestProxy::requiresAudio): Deleted, unused.
(WebKit::UserMediaPermissionRequestProxy::requiresVideo): Ditto.
(WebKit::UserMediaPermissionRequestProxy::firstVideoDeviceUID): Ditto.
(WebKit::UserMediaPermissionRequestProxy::firstAudioDeviceUID): Ditto.

* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::requestUserMediaPermissionForFrame): Pass through parameter for top
  level document security context.
(WebKit::WebPageProxy::checkUserMediaPermissionForFrame): Ditto.
* UIProcess/WebPageProxy.h:
* UIProcess/WebPageProxy.messages.in:

* WebKit2.xcodeproj/project.pbxproj: Add WKFrameHandleRef.cpp|.h.

* WebProcess/MediaStream/UserMediaPermissionRequestManager.cpp:
(WebKit::UserMediaPermissionRequestManager::startUserMediaRequest): Pass through parameter for top
  level document security context.
(WebKit::UserMediaPermissionRequestManager::startUserMediaPermissionCheck): Ditto.
(WebKit::UserMediaPermissionRequestManager::didCompleteUserMediaPermissionCheck): Pass through
  device id hash salt.
* WebProcess/MediaStream/UserMediaPermissionRequestManager.h:

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

Tools:

* WebKitTestRunner/InjectedBundle/InjectedBundle.cpp:
(WTR::InjectedBundle::setUserMediaPermissionForOrigin): Take top level document origin.
* WebKitTestRunner/InjectedBundle/InjectedBundle.h:

* WebKitTestRunner/InjectedBundle/TestRunner.cpp:
(WTR::TestRunner::setUserMediaPermissionForOrigin): Ditto.
* WebKitTestRunner/InjectedBundle/TestRunner.h:

* WebKitTestRunner/TestController.cpp:
(WTR::decidePolicyForUserMediaPermissionRequest): Pass through top level document origin.
(WTR::checkUserMediaPermissionForOrigin): Ditto.
(WTR::TestController::resetStateToConsistentValues): m_userMediaOriginPermissions -> m_cahcedUserMediaPermissions.
(WTR::originUserVisibleName): Return a String.
(WTR::userMediaOriginHash): Create a hash of the origin plus top level document origin.
(WTR::TestController::saltForOrigin): Return salt for an origin.
(WTR::TestController::setUserMediaPermissionForOrigin): Return permission for an origin.
(WTR::TestController::handleCheckOfUserMediaPermissionForOrigin):
(WTR::TestController::handleUserMediaPermissionRequest):
(WTR::TestController::decidePolicyForUserMediaPermissionRequestIfPossible):
(WTR::OriginSettings::OriginSettings): New, class to cache settings for an origin.
(WTR::OriginSettings::persistentPermission): Persistent permissions for origin.
(WTR::OriginSettings::setPersistentPermission): Set permissions for origin.
(WTR::OriginSettings::persistentSalt): Return the persistent salt for the origin, if any.
(WTR::OriginSettings::setPersistentSalt): Set the persistent salt for the origin
(WTR::OriginSettings::ephemeralSalts): Return hashmap used to store per-frame salts.
* WebKitTestRunner/TestController.h:

* WebKitTestRunner/TestInvocation.cpp:
(WTR::TestInvocation::didReceiveMessageFromInjectedBundle):

LayoutTests:

* fast/mediastream/MediaDevices-enumerateDevices-expected.txt:
* fast/mediastream/MediaDevices-enumerateDevices.html:
* http/tests/media/media-stream/enumerate-devices-source-id-expected.txt: Added.
* http/tests/media/media-stream/enumerate-devices-source-id-persistent-expected.txt: Added.
* http/tests/media/media-stream/enumerate-devices-source-id-persistent.html: Added.
* http/tests/media/media-stream/enumerate-devices-source-id.html: Added.
* http/tests/media/media-stream/resources/enumerate-devices-source-id-frame.html: Added.

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

62 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/mediastream/MediaDevices-enumerateDevices-expected.txt
LayoutTests/fast/mediastream/MediaDevices-enumerateDevices.html
LayoutTests/http/tests/media/media-stream/enumerate-devices-source-id-expected.txt [new file with mode: 0644]
LayoutTests/http/tests/media/media-stream/enumerate-devices-source-id-persistent-expected.txt [new file with mode: 0644]
LayoutTests/http/tests/media/media-stream/enumerate-devices-source-id-persistent.html [new file with mode: 0644]
LayoutTests/http/tests/media/media-stream/enumerate-devices-source-id.html [new file with mode: 0644]
LayoutTests/http/tests/media/media-stream/resources/enumerate-devices-source-id-frame.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/Modules/mediastream/MediaDevicesRequest.cpp
Source/WebCore/Modules/mediastream/MediaDevicesRequest.h
Source/WebCore/Modules/mediastream/UserMediaPermissionCheck.cpp
Source/WebCore/Modules/mediastream/UserMediaPermissionCheck.h
Source/WebCore/Modules/mediastream/UserMediaRequest.cpp
Source/WebCore/Modules/mediastream/UserMediaRequest.h
Source/WebCore/html/HTMLMediaElement.cpp
Source/WebCore/html/HTMLMediaElement.h
Source/WebCore/platform/graphics/MediaPlayer.h
Source/WebCore/platform/mediastream/MediaStreamTrackSourcesRequestClient.h
Source/WebCore/platform/mediastream/mac/RealtimeMediaSourceCenterMac.cpp
Source/WebCore/platform/mock/MockRealtimeMediaSourceCenter.cpp
Source/WebKit/mac/ChangeLog
Source/WebKit/mac/WebCoreSupport/WebUserMediaClient.mm
Source/WebKit2/CMakeLists.txt
Source/WebKit2/ChangeLog
Source/WebKit2/Shared/API/c/WKBase.h
Source/WebKit2/UIProcess/API/APIUIClient.h
Source/WebKit2/UIProcess/API/C/WKAPICast.h
Source/WebKit2/UIProcess/API/C/WKFrameHandleRef.cpp [new file with mode: 0644]
Source/WebKit2/UIProcess/API/C/WKFrameHandleRef.h [new file with mode: 0644]
Source/WebKit2/UIProcess/API/C/WKFrameInfoRef.cpp
Source/WebKit2/UIProcess/API/C/WKFrameInfoRef.h
Source/WebKit2/UIProcess/API/C/WKPage.cpp
Source/WebKit2/UIProcess/API/C/WKPageUIClient.h
Source/WebKit2/UIProcess/API/C/WKUserMediaPermissionCheck.cpp
Source/WebKit2/UIProcess/API/C/WKUserMediaPermissionCheck.h
Source/WebKit2/UIProcess/API/gtk/WebKitUIClient.cpp
Source/WebKit2/UIProcess/API/gtk/WebKitUserMediaPermissionRequest.cpp
Source/WebKit2/UIProcess/API/gtk/WebKitUserMediaPermissionRequestPrivate.h
Source/WebKit2/UIProcess/UserMediaPermissionCheckProxy.cpp
Source/WebKit2/UIProcess/UserMediaPermissionCheckProxy.h
Source/WebKit2/UIProcess/UserMediaPermissionRequestManagerProxy.cpp
Source/WebKit2/UIProcess/UserMediaPermissionRequestManagerProxy.h
Source/WebKit2/UIProcess/UserMediaPermissionRequestProxy.h
Source/WebKit2/UIProcess/WebPageProxy.cpp
Source/WebKit2/UIProcess/WebPageProxy.h
Source/WebKit2/UIProcess/WebPageProxy.messages.in
Source/WebKit2/WebKit2.xcodeproj/project.pbxproj
Source/WebKit2/WebProcess/MediaStream/UserMediaPermissionRequestManager.cpp
Source/WebKit2/WebProcess/MediaStream/UserMediaPermissionRequestManager.h
Source/WebKit2/WebProcess/WebPage/WebPage.cpp
Source/WebKit2/WebProcess/WebPage/WebPage.h
Source/WebKit2/WebProcess/WebPage/WebPage.messages.in
Tools/ChangeLog
Tools/WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl
Tools/WebKitTestRunner/InjectedBundle/InjectedBundle.cpp
Tools/WebKitTestRunner/InjectedBundle/InjectedBundle.h
Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp
Tools/WebKitTestRunner/InjectedBundle/TestRunner.h
Tools/WebKitTestRunner/TestController.cpp
Tools/WebKitTestRunner/TestController.h
Tools/WebKitTestRunner/TestInvocation.cpp

index 0c3b61b..7b971c2 100644 (file)
@@ -1,3 +1,19 @@
+2016-02-25  Eric Carlson  <eric.carlson@apple.com>
+
+        [MediaStream] MediaDeviceInfo deviceId and groupId must be unique to the page's origin
+        https://bugs.webkit.org/show_bug.cgi?id=153163
+        <rdar://problem/24334526>
+
+        Reviewed by Tim Horton.
+
+        * fast/mediastream/MediaDevices-enumerateDevices-expected.txt:
+        * fast/mediastream/MediaDevices-enumerateDevices.html:
+        * http/tests/media/media-stream/enumerate-devices-source-id-expected.txt: Added.
+        * http/tests/media/media-stream/enumerate-devices-source-id-persistent-expected.txt: Added.
+        * http/tests/media/media-stream/enumerate-devices-source-id-persistent.html: Added.
+        * http/tests/media/media-stream/enumerate-devices-source-id.html: Added.
+        * http/tests/media/media-stream/resources/enumerate-devices-source-id-frame.html: Added.
+
 2016-02-24  Joseph Pecoraro  <pecoraro@apple.com>
 
         Web Inspector: Expose Proxy target and handler internal properties to Inspector
index b40da44..1298719 100644 (file)
@@ -24,7 +24,7 @@ PASS captureDevice.label is ""
 PASS captureDevice.groupId is non-null.
 
 
-*** Calling mediaDevices.enumerateDevices without persistent access, and without a media stream track
+*** Calling mediaDevices.enumerateDevices with persistent access, and without a media stream track
 
 PASS captureDevices.length is non-zero.
 
@@ -33,12 +33,14 @@ PASS captureDevice.deviceId is non-null.
 PASS captureDevice.label is non-null.
 PASS captureDevice.label is not ""
 PASS captureDevice.groupId is non-null.
+PASS deviceIds.indexOf(captureDevice.deviceId) is not -1
 
 PASS captureDevice.kind is non-null.
 PASS captureDevice.deviceId is non-null.
 PASS captureDevice.label is non-null.
 PASS captureDevice.label is not ""
 PASS captureDevice.groupId is non-null.
+PASS deviceIds.indexOf(captureDevice.deviceId) is not -1
 
 
 *** Calling mediaDevices.enumerateDevices without persistent access, with a media stream track
@@ -50,12 +52,14 @@ PASS captureDevice.deviceId is non-null.
 PASS captureDevice.label is non-null.
 PASS captureDevice.label is not ""
 PASS captureDevice.groupId is non-null.
+PASS deviceIds.indexOf(captureDevice.deviceId) is not -1
 
 PASS captureDevice.kind is non-null.
 PASS captureDevice.deviceId is non-null.
 PASS captureDevice.label is non-null.
 PASS captureDevice.label is not ""
 PASS captureDevice.groupId is non-null.
+PASS deviceIds.indexOf(captureDevice.deviceId) is not -1
 
 PASS successfullyParsed is true
 
index fdcf9b5..3e2fa32 100644 (file)
@@ -10,6 +10,7 @@
             var captureDevices;
             var captureDevice;
             var havePermission;
+            var deviceIds = [];
 
             description("Tests MediaDevices.enumerateDevices()");
             window.jsTestIsAsync = true;
                             else
                                 shouldBeEmptyString("captureDevice.label");
                             shouldBeNonNull("captureDevice.groupId");
+                            
+                            if (deviceIds.length < 2)
+                                deviceIds.push(captureDevice.deviceId);
+                            else
+                                shouldNotBe("deviceIds.indexOf(captureDevice.deviceId)", "-1");
+
                             debug("");
                         });
                         if (next)
@@ -51,7 +58,7 @@
             {
                 if (window.testRunner) {
                     testRunner.setUserMediaPermission(true);
-                    testRunner.setUserMediaPermissionForOrigin(false, document.location.href);
+                    testRunner.setUserMediaPermissionForOrigin(false, document.location.href, "");
                 }
 
                 navigator.mediaDevices
                     })
                     .catch(function(err) {
                         testFailed(`mediaDevices.getUserMedia() failed with ${err.name}: ${err.message}`);
+                        finishJSTest();
                     });
             }
             
             function grantPermission()
             {
                 if (window.testRunner)
-                    testRunner.setUserMediaPermissionForOrigin(true, document.location.href);
+                    testRunner.setUserMediaPermissionForOrigin(true, document.location.href, "");
 
-                debug(`<br>*** Calling mediaDevices.enumerateDevices without persistent access, and without a media stream track<br>`);
+                debug(`<br>*** Calling mediaDevices.enumerateDevices with persistent access, and without a media stream track<br>`);
                 havePermission = true;
                 enumerate(createStream);
             }
diff --git a/LayoutTests/http/tests/media/media-stream/enumerate-devices-source-id-expected.txt b/LayoutTests/http/tests/media/media-stream/enumerate-devices-source-id-expected.txt
new file mode 100644 (file)
index 0000000..b7988ab
--- /dev/null
@@ -0,0 +1,27 @@
+
+Tests that mediaDevices.enumerateDevices returns a unique ID for deviceId in each domain.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS : device id 1 is unique
+PASS : device id 2 is unique
+PASS : device id 3 is unique
+PASS : device id 4 is unique
+PASS : device id 5 is unique
+PASS : device id 6 is unique
+PASS : device id 7 is unique
+PASS : device id 8 is unique
+PASS : device id 9 is unique
+PASS : device id 10 is unique
+PASS : device id 11 is unique
+PASS : device id 12 is unique
+
+PASS : all device IDs are unique
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/http/tests/media/media-stream/enumerate-devices-source-id-persistent-expected.txt b/LayoutTests/http/tests/media/media-stream/enumerate-devices-source-id-persistent-expected.txt
new file mode 100644 (file)
index 0000000..f009c5e
--- /dev/null
@@ -0,0 +1,16 @@
+
+Tests that mediaDevices.enumerateDevices returns a persistent deviceId when appropriate.
+http://localhost:8000 has persistent permission, so IDs must persist across frames.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+
+PASS : device IDs in http://localhost:8000 persist, all others are unique
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/http/tests/media/media-stream/enumerate-devices-source-id-persistent.html b/LayoutTests/http/tests/media/media-stream/enumerate-devices-source-id-persistent.html
new file mode 100644 (file)
index 0000000..2a0d3de
--- /dev/null
@@ -0,0 +1,72 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <style>
+            iframe { border: 1px solid black; }
+        </style>
+        <script src="../../../../resources/js-test-pre.js"></script>
+        <script>
+            var frameInfos = [];
+            window.jsTestIsAsync = true;
+
+            if (window.testRunner) {
+                testRunner.setUserMediaPermission(true);
+                testRunner.setUserMediaPermissionForOrigin(true, "http://localhost:8000", location.href);
+            }
+
+            function setup()
+            {
+                description("Tests that mediaDevices.enumerateDevices returns a persistent deviceId when appropriate." 
+                + "<br>http://localhost:8000 has persistent permission, so IDs must persist across frames.");
+            }
+
+            function handler(event) 
+            {
+                var idCounts = [];
+
+                event.data.deviceIds.forEach(function(id) {
+                    frameInfos.push({origin : event.data.origin, deviceId : id});
+                    idCounts[id] = idCounts[id] === undefined ? 0 : ++idCounts[id];
+                });
+
+                if (frameInfos.length != 6)
+                    return;
+
+                var success = true;
+                for (var i = 0; i < frameInfos.length; i++) {
+                    var deviceId = frameInfos[i].deviceId;
+                    if (frameInfos[i].origin.indexOf("http://localhost:8000") == 0) {
+                        if (idCounts[deviceId] < 2) {
+                            testFailed(`: device ID in ${frameInfos[i].origin} is unique`);
+                            success = false;
+                        }
+                    } else {
+                        if (idCounts[deviceId] == 1) {
+                            testFailed(`: device ID in ${frameInfos[i].origin} is not unique`);
+                            success = false;
+                        }
+                    }
+                }
+
+                debug('');
+                if (success)
+                    testPassed(`: device IDs in http://localhost:8000 persist, all others are unique`);
+
+                debug('');
+                finishJSTest();
+            }
+
+            addEventListener("message", handler, false);
+
+        </script> 
+    </head>
+    <body onload="setup()">
+        <iframe src="http://localhost:8000/media/media-stream/resources/enumerate-devices-source-id-frame.html"></iframe>
+        <br>
+        <iframe src="http://127.0.0.1:8000/media/media-stream/resources/enumerate-devices-source-id-frame.html"></iframe>
+        <br>
+        <iframe src="http://localhost:8000/media/media-stream/resources/enumerate-devices-source-id-frame.html"></iframe>
+        <div id="console"></div>
+        <script src="../../../../resources/js-test-post.js"></script>
+    </body>
+</html>
diff --git a/LayoutTests/http/tests/media/media-stream/enumerate-devices-source-id.html b/LayoutTests/http/tests/media/media-stream/enumerate-devices-source-id.html
new file mode 100644 (file)
index 0000000..fa07c94
--- /dev/null
@@ -0,0 +1,63 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <style>
+            iframe { border: 1px solid black; }
+        </style>
+        <script src="../../../../resources/js-test-pre.js"></script>
+        <script>
+            var frameInfos = [];
+            window.jsTestIsAsync = true;
+
+            if (window.testRunner)
+                testRunner.setUserMediaPermission(true);
+
+            function setup()
+            {
+                description("Tests that mediaDevices.enumerateDevices returns a unique ID for deviceId in each domain.");
+            }
+
+            function handler(event) 
+            {
+                event.data.deviceIds.forEach(function(id) {
+                    frameInfos.push({origin : event.data.origin, deviceId : id});
+                });
+
+                if (frameInfos.length != 12)
+                    return;
+
+                var success = true;
+                var idOrigins = [];
+                for (var i = 0; i < frameInfos.length; i++) {
+                    var deviceId = frameInfos[i].deviceId;
+                    if (idOrigins[deviceId] === undefined) {
+                        idOrigins[deviceId] = frameInfos[i].origin;
+                        testPassed(`: device id ${i + 1} is unique`);
+                    } else {
+                        testFailed(`Duplicate device IDs in ${frameInfos[i].origin} and ${idOrigins[deviceId]}`);
+                        success = false;
+                    }
+                }
+
+                debug('');
+                if (success)
+                    testPassed(`: all device IDs are unique`);
+
+                debug('');
+                finishJSTest();
+            }
+
+            addEventListener("message", handler, false);
+
+        </script> 
+    </head>
+    <body onload="setup()">
+        <iframe src="http://localhost:8000/media/media-stream/resources/enumerate-devices-source-id-frame.html"></iframe>
+        <br>
+        <iframe src="http://127.0.0.1:8000/media/media-stream/resources/enumerate-devices-source-id-frame.html"></iframe>
+        <br>
+        <iframe src="http://localhost:8000/media/media-stream/resources/enumerate-devices-source-id-frame.html"></iframe>
+        <div id="console"></div>
+        <script src="../../../../resources/js-test-post.js"></script>
+    </body>
+</html>
diff --git a/LayoutTests/http/tests/media/media-stream/resources/enumerate-devices-source-id-frame.html b/LayoutTests/http/tests/media/media-stream/resources/enumerate-devices-source-id-frame.html
new file mode 100644 (file)
index 0000000..cbee8c9
--- /dev/null
@@ -0,0 +1,54 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <style>
+            iframe { border: 1px solid black; }
+        </style>
+        <script>
+            function log(msg)
+            {
+                document.getElementById("console").innerHTML += msg + "<br>";
+            }
+
+            function test(event)
+            {
+                navigator.mediaDevices.enumerateDevices()
+                    .then(function(devices) {
+                        var result = {
+                            origin: document.origin, 
+                            deviceIds: [devices[0].deviceId, devices[1].deviceId]
+                        };
+
+                        parent.postMessage(result, "*");
+                    })
+                    .catch(function(err) {
+                        log(`enumerateDevices failed: ${err.name} - ${err.message}`);
+                    });
+                
+                var parentPage = document.referrer.split('/').pop();
+                if (parentPage != "enumerate-devices-source-id.html")
+                    return;
+
+                var iframe = document.createElement('iframe');
+                iframe.src = location.href;
+                document.body.appendChild(iframe);
+            }
+
+            function handler(event) 
+            {
+                var result = {
+                    origin: `${event.data.origin} in ${document.origin}`, 
+                    deviceIds: event.data.deviceIds
+                };
+
+                parent.postMessage(result, "*");
+            }
+
+            addEventListener("message", handler, false);
+
+        </script> 
+    </head>
+    <body onload="test()">
+        <pre id="console"></pre>
+    </body>
+</html>
index f40aef6..bae6e8d 100644 (file)
@@ -1,3 +1,59 @@
+2016-02-25  Eric Carlson  <eric.carlson@apple.com>
+
+        [MediaStream] MediaDeviceInfo deviceId and groupId must be unique to the page's origin
+        https://bugs.webkit.org/show_bug.cgi?id=153163
+        <rdar://problem/24334526>
+
+        Reviewed by Tim Horton.
+
+        Tests: http/tests/media/media-stream/enumerate-devices-source-id-persistent.html
+               http/tests/media/media-stream/enumerate-devices-source-id.html
+
+        * Modules/mediastream/MediaDevicesRequest.cpp:
+        (WebCore::MediaDevicesRequest::start): Don't check document.hasHadActiveMediaStreamTrack, do it
+          in didCompleteTrackSourceInfoRequest where we need the information.
+        (WebCore::MediaDevicesRequest::didCompletePermissionCheck): Renamed from didCompleteCheck, save
+          device ID hash string.
+        (WebCore::hashString): Hash a string with SHA1.
+        (WebCore::MediaDevicesRequest::hashID): Hash and ID.
+        (WebCore::MediaDevicesRequest::didCompleteTrackSourceInfoRequest): Hash deviceId and groupId.
+        (WebCore::MediaDevicesRequest::didCompleteCheck): Deleted.
+        (WebCore::MediaDevicesRequest::getTrackSources): Deleted.
+        (WebCore::MediaDevicesRequest::didCompleteRequest): Deleted.
+        * Modules/mediastream/MediaDevicesRequest.h:
+
+        * Modules/mediastream/UserMediaPermissionCheck.cpp:
+        (WebCore::UserMediaPermissionCheck::userMediaDocumentOrigin): Renamed from securityOrigin.
+        (WebCore::UserMediaPermissionCheck::topLevelDocumentOrigin): New, return the top level document origin.
+        (WebCore::UserMediaPermissionCheck::setUserMediaAccessInfo): Renamed from setHasPersistentPermission.
+        (WebCore::UserMediaPermissionCheck::securityOrigin): Deleted.
+        (WebCore::UserMediaPermissionCheck::setHasPersistentPermission): Deleted.
+        * Modules/mediastream/UserMediaPermissionCheck.h:
+
+        * Modules/mediastream/UserMediaRequest.cpp:
+        (WebCore::UserMediaRequest::userMediaDocumentOrigin): Renamed from securityOrigin.
+        (WebCore::UserMediaRequest::topLevelDocumentOrigin): New, return the top level document origin.
+        (WebCore::UserMediaRequest::securityOrigin): Deleted.
+        * Modules/mediastream/UserMediaRequest.h:
+        (WebCore::UserMediaRequest::requiresAudio): Deleted, unused.
+        (WebCore::UserMediaRequest::requiresVideo): Ditto.
+
+        * html/HTMLMediaElement.cpp:
+        (WebCore::HTMLMediaElement::mediaPlayerMediaDeviceIdentifierStorageDirectory): Deleted, unused.
+        * html/HTMLMediaElement.h:
+
+        * platform/graphics/MediaPlayer.h:
+        (WebCore::MediaPlayerClient::mediaPlayerMediaDeviceIdentifierStorageDirectory): Deleted.
+
+        * platform/mediastream/MediaStreamTrackSourcesRequestClient.h:
+        (WebCore::MediaStreamTrackSourcesRequestClient::didCompleteTrackSourceInfoRequest): Renamed from didCompleteRequest.
+
+        * platform/mediastream/mac/RealtimeMediaSourceCenterMac.cpp:
+        (WebCore::RealtimeMediaSourceCenterMac::getMediaStreamTrackSources): Ditto.
+
+        * platform/mock/MockRealtimeMediaSourceCenter.cpp:
+        (WebCore::MockRealtimeMediaSourceCenter::getMediaStreamTrackSources): Ditto.
+
 2016-02-24  Carlos Garcia Campos  <cgarcia@igalia.com>
 
         [GTK] Tearing when entering AC mode
index ad3b5f0..1bcf8be 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -35,7 +35,9 @@
 #include "JSMediaDeviceInfo.h"
 #include "RealtimeMediaSourceCenter.h"
 #include "SecurityOrigin.h"
+#include "UserMediaController.h"
 #include <wtf/MainThread.h>
+#include <wtf/SHA1.h>
 
 namespace WebCore {
 
@@ -77,54 +79,88 @@ void MediaDevicesRequest::contextDestroyed()
 void MediaDevicesRequest::start()
 {
     m_protector = this;
-
-    if (Document* document = downcast<Document>(scriptExecutionContext())) {
-        m_canShowLabels = document->hasHadActiveMediaStreamTrack();
-        if (m_canShowLabels) {
-            getTrackSources();
-            return;
-        }
-    }
-
     m_permissionCheck = UserMediaPermissionCheck::create(*downcast<Document>(scriptExecutionContext()), *this);
     m_permissionCheck->start();
 }
 
-void MediaDevicesRequest::didCompleteCheck(bool canAccess)
+void MediaDevicesRequest::didCompletePermissionCheck(const String& salt, bool canAccess)
 {
     m_permissionCheck->setClient(nullptr);
     m_permissionCheck = nullptr;
 
-    m_canShowLabels = canAccess;
-    getTrackSources();
-}
+    m_idHashSalt = salt;
+    m_havePersistentPermission = canAccess;
 
-void MediaDevicesRequest::getTrackSources()
-{
     callOnMainThread([this] {
         RealtimeMediaSourceCenter::singleton().getMediaStreamTrackSources(this);
     });
 }
 
-void MediaDevicesRequest::didCompleteRequest(const TrackSourceInfoVector& capturedDevices)
+static void hashString(SHA1& sha1, const String& string)
+{
+    if (string.isEmpty())
+        return;
+
+    if (string.is8Bit() && string.containsOnlyASCII()) {
+        const uint8_t nullByte = 0;
+        sha1.addBytes(string.characters8(), string.length());
+        sha1.addBytes(&nullByte, 1);
+        return;
+    }
+
+    auto utf8 = string.utf8();
+    sha1.addBytes(reinterpret_cast<const uint8_t*>(utf8.data()), utf8.length() + 1); // Include terminating null byte.
+}
+
+String MediaDevicesRequest::hashID(const String& id)
 {
-    if (!m_scriptExecutionContext) {
+    if (id.isEmpty() || m_idHashSalt.isEmpty())
+        return emptyString();
+
+    SHA1 sha1;
+
+    hashString(sha1, id);
+    hashString(sha1, m_idHashSalt);
+
+    SHA1::Digest digest;
+    sha1.computeHash(digest);
+
+    return SHA1::hexDigest(digest).data();
+}
+
+void MediaDevicesRequest::didCompleteTrackSourceInfoRequest(const TrackSourceInfoVector& captureDevices)
+{
+    if (!scriptExecutionContext()) {
         m_protector = nullptr;
         return;
     }
 
-    Vector<RefPtr<MediaDeviceInfo>> deviceInfo;
-    for (auto device : capturedDevices) {
-        TrackSourceInfo* trackInfo = device.get();
-        String deviceType = trackInfo->kind() == TrackSourceInfo::SourceKind::Audio ? MediaDeviceInfo::audioInputType() : MediaDeviceInfo::videoInputType();
+    Document& document = downcast<Document>(*scriptExecutionContext());
+    UserMediaController* controller = UserMediaController::from(document.page());
+    if (!controller) {
+        m_protector = nullptr;
+        return;
+    }
+
+    Vector<RefPtr<MediaDeviceInfo>> devices;
+    for (auto deviceInfo : captureDevices) {
+        String deviceType = deviceInfo->kind() == TrackSourceInfo::SourceKind::Audio ? MediaDeviceInfo::audioInputType() : MediaDeviceInfo::videoInputType();
+        AtomicString label = emptyAtom;
+        if (m_havePersistentPermission || document.hasHadActiveMediaStreamTrack())
+            label = deviceInfo->label();
+
+        String id = hashID(deviceInfo->persistentId());
+        if (id.isEmpty())
+            continue;
+
+        String groupId = hashID(deviceInfo->groupId());
 
-        AtomicString label = m_canShowLabels ? trackInfo->label() : emptyAtom;
-        deviceInfo.append(MediaDeviceInfo::create(m_scriptExecutionContext, label, trackInfo->id(), trackInfo->groupId(), deviceType));
+        devices.append(MediaDeviceInfo::create(scriptExecutionContext(), label, id, groupId, deviceType));
     }
 
     RefPtr<MediaDevicesRequest> protectedThis(this);
-    callOnMainThread([protectedThis, deviceInfo] {
-        protectedThis->m_promise.resolve(deviceInfo);
+    callOnMainThread([protectedThis, devices] {
+        protectedThis->m_promise.resolve(devices);
     });
     m_protector = nullptr;
 
index ffcc55e..3ade5f1 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -59,23 +59,24 @@ public:
 private:
     MediaDevicesRequest(ScriptExecutionContext*, MediaDevices::EnumerateDevicesPromise&&);
 
-    void getTrackSources();
-
     // MediaStreamTrackSourcesRequestClient
     const String& requestOrigin() const final;
-    void didCompleteRequest(const TrackSourceInfoVector&) final;
+    void didCompleteTrackSourceInfoRequest(const TrackSourceInfoVector&) final;
 
     // ContextDestructionObserver
     void contextDestroyed() override final;
 
     // UserMediaPermissionCheckClient
-    void didCompleteCheck(bool) override final;
+    void didCompletePermissionCheck(const String&, bool) override final;
+
+    String hashID(const String&);
 
     MediaDevices::EnumerateDevicesPromise m_promise;
     RefPtr<MediaDevicesRequest> m_protector;
     RefPtr<UserMediaPermissionCheck> m_permissionCheck;
 
-    bool m_canShowLabels { false };
+    String m_idHashSalt;
+    bool m_havePersistentPermission { false };
 };
 
 } // namespace WebCore
index 1ba8648..47c35ee 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 #include "ExceptionCode.h"
 #include "Frame.h"
 #include "JSMediaDeviceInfo.h"
+#include "MainFrame.h"
 #include "RealtimeMediaSourceCenter.h"
 #include "SecurityOrigin.h"
 #include "UserMediaController.h"
-#include <wtf/MainThread.h>
 
 namespace WebCore {
 
@@ -55,14 +55,27 @@ UserMediaPermissionCheck::~UserMediaPermissionCheck()
 {
 }
 
-SecurityOrigin* UserMediaPermissionCheck::securityOrigin() const
+SecurityOrigin* UserMediaPermissionCheck::userMediaDocumentOrigin() const
 {
-    if (scriptExecutionContext())
-        return scriptExecutionContext()->securityOrigin();
+    if (m_scriptExecutionContext)
+        return m_scriptExecutionContext->securityOrigin();
 
     return nullptr;
 }
 
+SecurityOrigin* UserMediaPermissionCheck::topLevelDocumentOrigin() const
+{
+    if (!m_scriptExecutionContext)
+        return nullptr;
+
+    if (Frame* frame = downcast<Document>(*scriptExecutionContext()).frame()) {
+        if (frame->isMainFrame())
+            return nullptr;
+    }
+
+    return m_scriptExecutionContext->topOrigin();
+}
+
 void UserMediaPermissionCheck::contextDestroyed()
 {
     ContextDestructionObserver::contextDestroyed();
@@ -80,12 +93,13 @@ void UserMediaPermissionCheck::start()
     controller->checkUserMediaPermission(*this);
 }
 
-void UserMediaPermissionCheck::setHasPersistentPermission(bool mode)
+void UserMediaPermissionCheck::setUserMediaAccessInfo(const String& mediaDeviceIdentifierHashSalt, bool hasPersistentPermission)
 {
-    m_hasPersistentPermission = mode;
+    m_hasPersistentPermission = hasPersistentPermission;
+    m_mediaDeviceIdentifierHashSalt = mediaDeviceIdentifierHashSalt;
 
     if (m_client)
-        m_client->didCompleteCheck(m_hasPersistentPermission);
+        m_client->didCompletePermissionCheck(m_mediaDeviceIdentifierHashSalt, m_hasPersistentPermission);
 }
 
 } // namespace WebCore
index 16dde2c..476715e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -43,7 +43,7 @@ class UserMediaPermissionCheckClient {
 public:
     virtual ~UserMediaPermissionCheckClient() { }
 
-    virtual void didCompleteCheck(bool) = 0;
+    virtual void didCompletePermissionCheck(const String&, bool) = 0;
 };
 
 class UserMediaPermissionCheck final : public ContextDestructionObserver, public RefCounted<UserMediaPermissionCheck> {
@@ -55,9 +55,12 @@ public:
     void start();
     void setClient(UserMediaPermissionCheckClient* client) { m_client = client; }
 
-    WEBCORE_EXPORT void setHasPersistentPermission(bool);
+    WEBCORE_EXPORT SecurityOrigin* userMediaDocumentOrigin() const;
+    WEBCORE_EXPORT SecurityOrigin* topLevelDocumentOrigin() const;
 
-    WEBCORE_EXPORT SecurityOrigin* securityOrigin() const;
+    WEBCORE_EXPORT void setUserMediaAccessInfo(const String&, bool);
+
+    WEBCORE_EXPORT String mediaDeviceIdentifierHashSalt() const { return m_mediaDeviceIdentifierHashSalt; }
 
 private:
     UserMediaPermissionCheck(ScriptExecutionContext&, UserMediaPermissionCheckClient&);
@@ -66,6 +69,7 @@ private:
     virtual void contextDestroyed() override final;
 
     UserMediaPermissionCheckClient* m_client;
+    String m_mediaDeviceIdentifierHashSalt;
     bool m_hasPersistentPermission { false };
 };
 
index 0924dad..31ae479 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Copyright (C) 2011 Ericsson AB. All rights reserved.
  * Copyright (C) 2012 Google Inc. All rights reserved.
- * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2016 Apple Inc. All rights reserved.
  * Copyright (C) 2013 Nokia Corporation and/or its subsidiary(-ies).
  *
  * Redistribution and use in source and binary forms, with or without
@@ -44,6 +44,7 @@
 #include "JSMediaDeviceInfo.h"
 #include "JSMediaStream.h"
 #include "JSNavigatorUserMediaError.h"
+#include "MainFrame.h"
 #include "MediaConstraintsImpl.h"
 #include "MediaStream.h"
 #include "MediaStreamPrivate.h"
@@ -105,14 +106,27 @@ UserMediaRequest::~UserMediaRequest()
 {
 }
 
-SecurityOrigin* UserMediaRequest::securityOrigin() const
+SecurityOrigin* UserMediaRequest::userMediaDocumentOrigin() const
 {
     if (m_scriptExecutionContext)
         return m_scriptExecutionContext->securityOrigin();
 
     return nullptr;
 }
-    
+
+SecurityOrigin* UserMediaRequest::topLevelDocumentOrigin() const
+{
+    if (!m_scriptExecutionContext)
+        return nullptr;
+
+    if (Frame* frame = downcast<Document>(*scriptExecutionContext()).frame()) {
+        if (frame->isMainFrame())
+            return nullptr;
+    }
+
+    return m_scriptExecutionContext->topOrigin();
+}
+
 void UserMediaRequest::start()
 {
     // 1 - make sure the system is capable of supporting the audio and video constraints. We don't want to ask for
index ecea59a..9788f35 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2011 Ericsson AB. All rights reserved.
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2016 Apple Inc. All rights reserved.
  * Copyright (C) 2013 Nokia Corporation and/or its subsidiary(-ies).
  *
  * Redistribution and use in source and binary forms, with or without
@@ -60,15 +60,13 @@ public:
 
     ~UserMediaRequest();
 
-    WEBCORE_EXPORT SecurityOrigin* securityOrigin() const;
+    WEBCORE_EXPORT SecurityOrigin* userMediaDocumentOrigin() const;
+    WEBCORE_EXPORT SecurityOrigin* topLevelDocumentOrigin() const;
 
     void start();
     WEBCORE_EXPORT void userMediaAccessGranted(const String& audioDeviceUID, const String& videoDeviceUID);
     WEBCORE_EXPORT void userMediaAccessDenied();
 
-    bool requiresAudio() const { return m_audioDeviceUIDs.size(); }
-    bool requiresVideo() const { return m_videoDeviceUIDs.size(); }
-
     const Vector<String>& audioDeviceUIDs() const { return m_audioDeviceUIDs; }
     const Vector<String>& videoDeviceUIDs() const { return m_videoDeviceUIDs; }
 
index 4c755b8..aab2dbb 100644 (file)
@@ -2344,25 +2344,6 @@ void HTMLMediaElement::keyAdded()
 }
 #endif
 
-#if ENABLE(MEDIA_STREAM)
-String HTMLMediaElement::mediaPlayerMediaDeviceIdentifierStorageDirectory() const
-{
-    Settings* settings = document().settings();
-    if (!settings)
-        return emptyString();
-
-    String storageDirectory = settings->mediaDeviceIdentifierStorageDirectory();
-    if (storageDirectory.isEmpty())
-        return emptyString();
-
-    SecurityOrigin* origin = document().securityOrigin();
-    if (!origin)
-        return emptyString();
-
-    return pathByAppendingComponent(storageDirectory, origin->databaseIdentifier());
-}
-#endif
-
 void HTMLMediaElement::progressEventTimerFired()
 {
     ASSERT(m_player);
index d61df75..48bfe0d 100644 (file)
@@ -559,10 +559,6 @@ private:
     virtual String mediaPlayerMediaKeysStorageDirectory() const override;
 #endif
     
-#if ENABLE(MEDIA_STREAM)
-    virtual String mediaPlayerMediaDeviceIdentifierStorageDirectory() const override;
-#endif
-
 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
     virtual void mediaPlayerCurrentPlaybackTargetIsWirelessChanged(MediaPlayer*) override;
     void enqueuePlaybackTargetAvailabilityChangedEvent();
index 2faaa19..dbd4f8a 100644 (file)
@@ -213,11 +213,6 @@ public:
     virtual String mediaPlayerMediaKeysStorageDirectory() const { return emptyString(); }
 #endif
     
-#if ENABLE(MEDIA_STREAM)
-    virtual String mediaPlayerMediaDeviceIdentifierStorageDirectory() const { return emptyString(); }
-#endif
-
-    
 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
     virtual void mediaPlayerCurrentPlaybackTargetIsWirelessChanged(MediaPlayer*) { };
 #endif
index d18af07..67ced81 100644 (file)
@@ -87,7 +87,7 @@ public:
     virtual ~MediaStreamTrackSourcesRequestClient() { }
 
     virtual const String& requestOrigin() const = 0;
-    virtual void didCompleteRequest(const TrackSourceInfoVector&) = 0;
+    virtual void didCompleteTrackSourceInfoRequest(const TrackSourceInfoVector&) = 0;
 };
 
 
index 63c8eeb..2499cf3 100644 (file)
@@ -167,7 +167,7 @@ bool RealtimeMediaSourceCenterMac::getMediaStreamTrackSources(PassRefPtr<MediaSt
     TrackSourceInfoVector sources = AVCaptureDeviceManager::singleton().getSourcesInfo(requestClient->requestOrigin());
 
     callOnMainThread([this, requestClient, sources] {
-        requestClient->didCompleteRequest(sources);
+        requestClient->didCompleteTrackSourceInfoRequest(sources);
     });
 
     return true;
index 7c13c38..9093579 100644 (file)
@@ -160,7 +160,7 @@ bool MockRealtimeMediaSourceCenter::getMediaStreamTrackSources(PassRefPtr<MediaS
     sources.append(MockRealtimeMediaSource::trackSourceWithUID(MockRealtimeMediaSource::mockVideoSourcePersistentID(), nullptr));
 
     callOnMainThread([this, requestClient, sources] {
-        requestClient->didCompleteRequest(sources);
+        requestClient->didCompleteTrackSourceInfoRequest(sources);
     });
 
     return true;
index 08c2e71..62c13c3 100644 (file)
@@ -1,3 +1,17 @@
+2016-02-25  Eric Carlson  <eric.carlson@apple.com>
+
+        [MediaStream] MediaDeviceInfo deviceId and groupId must be unique to the page's origin
+        https://bugs.webkit.org/show_bug.cgi?id=153163
+        <rdar://problem/24334526>
+
+        Reviewed by Tim Horton.
+
+        * WebCoreSupport/WebUserMediaClient.mm:
+        (WebUserMediaClient::requestUserMediaAccess):
+        (WebUserMediaClient::checkUserMediaPermission):
+        (-[WebUserMediaPolicyCheckerListener allow]):
+        (-[WebUserMediaPolicyCheckerListener deny]):
+
 2016-02-24  Nikos Andronikos  <nikos.andronikos-webkit@cisra.canon.com.au>
 
         [web-animations] Add AnimationTimeline, DocumentTimeline and add extensions to Document interface
index 603e858..bfb282a 100644 (file)
@@ -141,7 +141,7 @@ void WebUserMediaClient::requestUserMediaAccess(UserMediaRequest& request)
     }
 
     WebUserMediaPolicyListener *listener = [[WebUserMediaPolicyListener alloc] initWithUserMediaRequest:&request];
-    WebSecurityOrigin *webOrigin = [[WebSecurityOrigin alloc] _initWithWebCoreSecurityOrigin:request.securityOrigin()];
+    WebSecurityOrigin *webOrigin = [[WebSecurityOrigin alloc] _initWithWebCoreSecurityOrigin:request.userMediaDocumentOrigin()];
 
     AddRequestToRequestMap(&request, listener);
     CallUIDelegate(m_webView, selector, webOrigin, listener);
@@ -169,12 +169,12 @@ void WebUserMediaClient::checkUserMediaPermission(UserMediaPermissionCheck& requ
 
     SEL selector = @selector(webView:checkPolicyForUserMediaRequestFromOrigin:listener:);
     if (![[m_webView UIDelegate] respondsToSelector:selector]) {
-        request.setHasPersistentPermission(false);
+        request.setUserMediaAccessInfo(emptyString(), false);
         return;
     }
 
     WebUserMediaPolicyCheckerListener *listener = [[WebUserMediaPolicyCheckerListener alloc] initWithUserMediaPermissionCheck:&request];
-    WebSecurityOrigin *webOrigin = [[WebSecurityOrigin alloc] _initWithWebCoreSecurityOrigin:request.securityOrigin()];
+    WebSecurityOrigin *webOrigin = [[WebSecurityOrigin alloc] _initWithWebCoreSecurityOrigin:request.userMediaDocumentOrigin()];
 
     AddPermissionCheckToMap(&request, listener);
     CallUIDelegate(m_webView, selector, webOrigin, listener);
@@ -288,7 +288,7 @@ void WebUserMediaClient::cancelUserMediaPermissionCheck(WebCore::UserMediaPermis
     if (!_request)
         return;
 
-    _request->setHasPersistentPermission(true);
+    _request->setUserMediaAccessInfo(_request->mediaDeviceIdentifierHashSalt(), true);
     RemovePermissionCheckFromMap(_request.get());
 #endif
 }
@@ -299,7 +299,7 @@ void WebUserMediaClient::cancelUserMediaPermissionCheck(WebCore::UserMediaPermis
     if (!_request)
         return;
 
-    _request->setHasPersistentPermission(true);
+    _request->setUserMediaAccessInfo(emptyString(), true);
     RemovePermissionCheckFromMap(_request.get());
 #endif
 }
index 6435960..ed2413c 100644 (file)
@@ -430,6 +430,7 @@ set(WebKit2_SOURCES
     UIProcess/API/C/WKDownload.cpp
     UIProcess/API/C/WKFormSubmissionListener.cpp
     UIProcess/API/C/WKFrame.cpp
+    UIProcess/API/C/WKFrameHandleRef.cpp
     UIProcess/API/C/WKFrameInfoRef.cpp
     UIProcess/API/C/WKFramePolicyListener.cpp
     UIProcess/API/C/WKGeolocationManager.cpp
index a6adbc3..b90065e 100644 (file)
@@ -1,3 +1,81 @@
+2016-02-25  Eric Carlson  <eric.carlson@apple.com>
+
+        [MediaStream] MediaDeviceInfo deviceId and groupId must be unique to the page's origin
+        https://bugs.webkit.org/show_bug.cgi?id=153163
+        <rdar://problem/24334526>
+
+        Reviewed by Tim Horton.
+
+        * CMakeLists.txt: Add WKFrameHandleRef.cpp.
+
+        * Shared/API/c/WKBase.h: Add WKFrameHandleRef.
+        * UIProcess/API/APIUIClient.h:
+        (API::UIClient::decidePolicyForUserMediaPermissionRequest): Add parameter top level document
+          security context.
+        (API::UIClient::checkUserMediaPermissionForOrigin): Ditto.
+
+        * UIProcess/API/C/WKAPICast.h: Add FrameHandle.
+
+        * UIProcess/API/C/WKFrameHandleRef.cpp: Added.
+        * UIProcess/API/C/WKFrameHandleRef.h: Added.
+
+        * UIProcess/API/C/WKFrameInfoRef.cpp:
+        (WKFrameInfoGetFrameHandleRef): Added.
+        * UIProcess/API/C/WKFrameInfoRef.h:
+
+        * UIProcess/API/C/WKPage.cpp:
+        (WKPageSetPageUIClient): Add parameters to decidePolicyForUserMediaPermissionRequest and
+          checkUserMediaPermissionForOrigin for top level document security context.
+
+        * UIProcess/API/C/WKPageUIClient.h: Ditto.
+
+        * UIProcess/API/C/WKUserMediaPermissionCheck.cpp:
+        (WKUserMediaPermissionCheckSetUserMediaAccessInfo): Renamed from WKUserMediaPermissionCheckSetHasPersistentPermission,
+          add parameter for top level document security context.
+        (WKUserMediaPermissionCheckSetHasPersistentPermission): Deleted.
+        * UIProcess/API/C/WKUserMediaPermissionCheck.h:
+
+        * UIProcess/API/gtk/WebKitUserMediaPermissionRequest.cpp:
+        (webkitUserMediaPermissionRequestCreate): Add top level document origin.
+
+        * UIProcess/UserMediaPermissionCheckProxy.cpp:
+        (WebKit::UserMediaPermissionCheckProxy::setUserMediaAccessInfo): Renamed from setHasPersistentPermission.
+        (WebKit::UserMediaPermissionCheckProxy::setHasPersistentPermission): Deleted.
+        * UIProcess/UserMediaPermissionCheckProxy.h:
+
+        * UIProcess/UserMediaPermissionRequestManagerProxy.cpp:
+        (WebKit::UserMediaPermissionRequestManagerProxy::didCompleteUserMediaPermissionCheck): Add parameter
+         for device id hash salt.
+        * UIProcess/UserMediaPermissionRequestManagerProxy.h:
+
+        * UIProcess/UserMediaPermissionRequestProxy.h:
+        (WebKit::UserMediaPermissionRequestProxy::requiresAudio): Deleted, unused.
+        (WebKit::UserMediaPermissionRequestProxy::requiresVideo): Ditto.
+        (WebKit::UserMediaPermissionRequestProxy::firstVideoDeviceUID): Ditto.
+        (WebKit::UserMediaPermissionRequestProxy::firstAudioDeviceUID): Ditto.
+
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::requestUserMediaPermissionForFrame): Pass through parameter for top
+          level document security context.
+        (WebKit::WebPageProxy::checkUserMediaPermissionForFrame): Ditto.
+        * UIProcess/WebPageProxy.h:
+        * UIProcess/WebPageProxy.messages.in:
+
+        * WebKit2.xcodeproj/project.pbxproj: Add WKFrameHandleRef.cpp|.h.
+
+        * WebProcess/MediaStream/UserMediaPermissionRequestManager.cpp:
+        (WebKit::UserMediaPermissionRequestManager::startUserMediaRequest): Pass through parameter for top
+          level document security context.
+        (WebKit::UserMediaPermissionRequestManager::startUserMediaPermissionCheck): Ditto.
+        (WebKit::UserMediaPermissionRequestManager::didCompleteUserMediaPermissionCheck): Pass through
+          device id hash salt.
+        * WebProcess/MediaStream/UserMediaPermissionRequestManager.h:
+
+        * WebProcess/WebPage/WebPage.cpp:
+        (WebKit::WebPage::didCompleteUserMediaPermissionCheck): Ditto.
+        * WebProcess/WebPage/WebPage.h:
+        * WebProcess/WebPage/WebPage.messages.in:
+
 2016-02-24  Carlos Garcia Campos  <cgarcia@igalia.com>
 
         [GTK] Tearing when entering AC mode
index 4f84aab..729577d 100644 (file)
@@ -99,6 +99,7 @@ typedef const struct OpaqueWKCookieManager* WKCookieManagerRef;
 typedef const struct OpaqueWKCredential* WKCredentialRef;
 typedef const struct OpaqueWKDownload* WKDownloadRef;
 typedef const struct OpaqueWKFormSubmissionListener* WKFormSubmissionListenerRef;
+typedef const struct OpaqueWKFrameHandle* WKFrameHandleRef;
 typedef const struct OpaqueWKFrameInfo* WKFrameInfoRef;
 typedef const struct OpaqueWKFrame* WKFrameRef;
 typedef const struct OpaqueWKFramePolicyListener* WKFramePolicyListenerRef;
index 0e5927f..0a9699a 100644 (file)
@@ -132,8 +132,8 @@ public:
 
     virtual bool runOpenPanel(WebKit::WebPageProxy*, WebKit::WebFrameProxy*, WebKit::WebOpenPanelParameters*, WebKit::WebOpenPanelResultListenerProxy*) { return false; }
     virtual bool decidePolicyForGeolocationPermissionRequest(WebKit::WebPageProxy*, WebKit::WebFrameProxy*, SecurityOrigin*, WebKit::GeolocationPermissionRequestProxy*) { return false; }
-    virtual bool decidePolicyForUserMediaPermissionRequest(WebKit::WebPageProxy&, WebKit::WebFrameProxy&, SecurityOrigin&, WebKit::UserMediaPermissionRequestProxy&) { return false; }
-    virtual bool checkUserMediaPermissionForOrigin(WebKit::WebPageProxy&, WebKit::WebFrameProxy&, SecurityOrigin&, WebKit::UserMediaPermissionCheckProxy&) { return false; }
+    virtual bool decidePolicyForUserMediaPermissionRequest(WebKit::WebPageProxy&, WebKit::WebFrameProxy&, SecurityOrigin&, SecurityOrigin&, WebKit::UserMediaPermissionRequestProxy&) { return false; }
+    virtual bool checkUserMediaPermissionForOrigin(WebKit::WebPageProxy&, WebKit::WebFrameProxy&, SecurityOrigin&, SecurityOrigin&, WebKit::UserMediaPermissionCheckProxy&) { return false; }
     virtual bool decidePolicyForNotificationPermissionRequest(WebKit::WebPageProxy*, SecurityOrigin*, WebKit::NotificationPermissionRequest*) { return false; }
 
     // Printing.
index ee7f2df..ad58d69 100644 (file)
@@ -51,6 +51,7 @@
 #include <WebCore/Settings.h>
 
 namespace API {
+class FrameHandle;
 class FrameInfo;
 class HitTestResult;
 class Navigation;
@@ -125,6 +126,7 @@ WK_ADD_API_MAPPING(WKCredentialRef, WebCredential)
 WK_ADD_API_MAPPING(WKDownloadRef, DownloadProxy)
 WK_ADD_API_MAPPING(WKFormSubmissionListenerRef, WebFormSubmissionListenerProxy)
 WK_ADD_API_MAPPING(WKFramePolicyListenerRef, WebFramePolicyListenerProxy)
+WK_ADD_API_MAPPING(WKFrameHandleRef, API::FrameHandle)
 WK_ADD_API_MAPPING(WKFrameInfoRef, API::FrameInfo)
 WK_ADD_API_MAPPING(WKFrameRef, WebFrameProxy)
 WK_ADD_API_MAPPING(WKGeolocationManagerRef, WebGeolocationManagerProxy)
diff --git a/Source/WebKit2/UIProcess/API/C/WKFrameHandleRef.cpp b/Source/WebKit2/UIProcess/API/C/WKFrameHandleRef.cpp
new file mode 100644 (file)
index 0000000..b39fca1
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "WKFrameHandleRef.h"
+
+#include "APIFrameHandle.h"
+#include "WKAPICast.h"
+
+using namespace WebKit;
+
+WKTypeID WKFrameHandleGetTypeID()
+{
+    return toAPI(API::FrameHandle::APIType);
+}
+
+uint64_t WKFrameHandleGetFrameID(WKFrameHandleRef frameHandleRef)
+{
+    return toImpl(frameHandleRef)->frameID();
+}
diff --git a/Source/WebKit2/UIProcess/API/C/WKFrameHandleRef.h b/Source/WebKit2/UIProcess/API/C/WKFrameHandleRef.h
new file mode 100644 (file)
index 0000000..30791a9
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WKFrameHandleRef_h
+#define WKFrameHandleRef_h
+
+#include <WebKit/WKBase.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+WK_EXPORT WKTypeID WKFrameHandleGetTypeID();
+
+WK_EXPORT uint64_t WKFrameHandleGetFrameID(WKFrameHandleRef);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // WKFrameHandleRef_h
index dbdd101..6ba5175 100644 (file)
@@ -26,6 +26,7 @@
 #include "config.h"
 #include "WKFrameInfoRef.h"
 
+#include "APIFrameHandle.h"
 #include "APIFrameInfo.h"
 #include "WKAPICast.h"
 
@@ -35,3 +36,8 @@ WKTypeID WKFrameInfoGetTypeID()
 {
     return toAPI(API::FrameInfo::APIType);
 }
+
+WKFrameHandleRef WKFrameInfoGetFrameHandleRef(WKFrameInfoRef frameInfoRef)
+{
+    return toAPI(&toImpl(frameInfoRef)->handle());
+}
index f7ddadd..e95472e 100644 (file)
@@ -34,6 +34,8 @@ extern "C" {
 
 WK_EXPORT WKTypeID WKFrameInfoGetTypeID();
 
+WK_EXPORT WKFrameHandleRef WKFrameInfoGetFrameHandleRef(WKFrameInfoRef);
+
 #ifdef __cplusplus
 }
 #endif
index 701a4c8..9fc89c2 100644 (file)
@@ -2063,21 +2063,21 @@ void WKPageSetPageUIClient(WKPageRef pageRef, const WKPageUIClientBase* wkClient
             return true;
         }
 
-        virtual bool decidePolicyForUserMediaPermissionRequest(WebPageProxy& page, WebFrameProxy& frame, API::SecurityOrigin& origin, UserMediaPermissionRequestProxy& permissionRequest) override
+        virtual bool decidePolicyForUserMediaPermissionRequest(WebPageProxy& page, WebFrameProxy& frame, API::SecurityOrigin& userMediaDocumentOrigin, API::SecurityOrigin& topLevelDocumentOrigin, UserMediaPermissionRequestProxy& permissionRequest) override
         {
             if (!m_client.decidePolicyForUserMediaPermissionRequest)
                 return false;
 
-            m_client.decidePolicyForUserMediaPermissionRequest(toAPI(&page), toAPI(&frame), toAPI(&origin), toAPI(&permissionRequest), m_client.base.clientInfo);
+            m_client.decidePolicyForUserMediaPermissionRequest(toAPI(&page), toAPI(&frame), toAPI(&userMediaDocumentOrigin), toAPI(&topLevelDocumentOrigin), toAPI(&permissionRequest), m_client.base.clientInfo);
             return true;
         }
 
-        virtual bool checkUserMediaPermissionForOrigin(WebPageProxy& page, WebFrameProxy& frame, API::SecurityOrigin& origin, UserMediaPermissionCheckProxy& request) override
+        virtual bool checkUserMediaPermissionForOrigin(WebPageProxy& page, WebFrameProxy& frame, API::SecurityOrigin& userMediaDocumentOrigin, API::SecurityOrigin& topLevelDocumentOrigin, UserMediaPermissionCheckProxy& request) override
         {
             if (!m_client.checkUserMediaPermissionForOrigin)
                 return false;
 
-            m_client.checkUserMediaPermissionForOrigin(toAPI(&page), toAPI(&frame), toAPI(&origin), toAPI(&request), m_client.base.clientInfo);
+            m_client.checkUserMediaPermissionForOrigin(toAPI(&page), toAPI(&frame), toAPI(&userMediaDocumentOrigin), toAPI(&topLevelDocumentOrigin), toAPI(&request), m_client.base.clientInfo);
             return true;
         }
         
index 2ab3595..5fdd3c4 100644 (file)
@@ -98,8 +98,8 @@ typedef void (*WKPageHideColorPickerCallback)(WKPageRef page, const void* client
 typedef void (*WKPageUnavailablePluginButtonClickedCallback)(WKPageRef page, WKPluginUnavailabilityReason pluginUnavailabilityReason, WKDictionaryRef pluginInfoDictionary, const void* clientInfo);
 typedef void (*WKPagePinnedStateDidChangeCallback)(WKPageRef page, const void* clientInfo);
 typedef void (*WKPageIsPlayingAudioDidChangeCallback)(WKPageRef page, const void* clientInfo);
-typedef void (*WKPageDecidePolicyForUserMediaPermissionRequestCallback)(WKPageRef page, WKFrameRef frame, WKSecurityOriginRef origin, WKUserMediaPermissionRequestRef permissionRequest, const void* clientInfo);
-typedef void (*WKCheckUserMediaPermissionCallback)(WKPageRef page, WKFrameRef frame, WKSecurityOriginRef origin, WKUserMediaPermissionCheckRef devicesRequest, const void *clientInfo);
+typedef void (*WKPageDecidePolicyForUserMediaPermissionRequestCallback)(WKPageRef page, WKFrameRef frame, WKSecurityOriginRef userMediaDocumentOrigin, WKSecurityOriginRef topLevelDocumentOrigin, WKUserMediaPermissionRequestRef permissionRequest, const void* clientInfo);
+typedef void (*WKCheckUserMediaPermissionCallback)(WKPageRef page, WKFrameRef frame, WKSecurityOriginRef userMediaDocumentOrigin, WKSecurityOriginRef topLevelDocumentOrigin, WKUserMediaPermissionCheckRef devicesRequest, const void *clientInfo);
 typedef void (*WKPageDidClickAutoFillButtonCallback)(WKPageRef page, WKTypeRef userData, const void *clientInfo);
 typedef void (*WKPageMediaSessionMetadataDidChangeCallback)(WKPageRef page, WKMediaSessionMetadataRef metadata, const void* clientInfo);
 
index 371c813..4403cd7 100644 (file)
@@ -40,8 +40,8 @@ WKTypeID WKUserMediaPermissionCheckGetTypeID()
     return toAPI(UserMediaPermissionCheckProxy::APIType);
 }
 
-void WKUserMediaPermissionCheckSetHasPersistentPermission(WKUserMediaPermissionCheckRef userMediaPermissionRequestRef, bool allowed)
+void WKUserMediaPermissionCheckSetUserMediaAccessInfo(WKUserMediaPermissionCheckRef userMediaPermissionRequestRef, WKStringRef mediaDeviceIdentifierHashSalt, bool allowed)
 {
-    toImpl(userMediaPermissionRequestRef)->setHasPersistentPermission(allowed);
+    toImpl(userMediaPermissionRequestRef)->setUserMediaAccessInfo(toWTFString(mediaDeviceIdentifierHashSalt), allowed);
 }
 
index e0cb0a3..d257845 100644 (file)
@@ -35,7 +35,7 @@ extern "C" {
 
 WK_EXPORT WKTypeID WKUserMediaPermissionCheckGetTypeID();
 
-WK_EXPORT void WKUserMediaPermissionCheckSetHasPersistentPermission(WKUserMediaPermissionCheckRef, bool);
+WK_EXPORT void WKUserMediaPermissionCheckSetUserMediaAccessInfo(WKUserMediaPermissionCheckRef, WKStringRef, bool);
 
 #ifdef __cplusplus
 }
index 5b0835b..0defc81 100644 (file)
@@ -174,9 +174,9 @@ private:
         return true;
     }
 
-    virtual bool decidePolicyForUserMediaPermissionRequest(WebPageProxy&, WebFrameProxy&, API::SecurityOrigin& securityOrigin, UserMediaPermissionRequestProxy& permissionRequest) override
+    virtual bool decidePolicyForUserMediaPermissionRequest(WebPageProxy&, WebFrameProxy&, API::SecurityOrigin& userMediaDocumentOrigin, API::SecurityOrigin& topLevelDocumentOrigin, UserMediaPermissionRequestProxy& permissionRequest) override
     {
-        GRefPtr<WebKitUserMediaPermissionRequest> userMediaPermissionRequest = adoptGRef(webkitUserMediaPermissionRequestCreate(permissionRequest, securityOrigin));
+        GRefPtr<WebKitUserMediaPermissionRequest> userMediaPermissionRequest = adoptGRef(webkitUserMediaPermissionRequestCreate(permissionRequest, userMediaDocumentOrigin, topLevelDocumentOrigin));
         webkitWebViewMakePermissionRequest(m_webView, WEBKIT_PERMISSION_REQUEST(userMediaPermissionRequest.get()));
         return true;
     }
index c62e8d6..5602ffd 100644 (file)
@@ -184,12 +184,13 @@ static void webkit_user_media_permission_request_class_init(WebKitUserMediaPermi
             WEBKIT_PARAM_READABLE));
 }
 
-WebKitUserMediaPermissionRequest* webkitUserMediaPermissionRequestCreate(UserMediaPermissionRequestProxy& request, API::SecurityOrigin& securityOrigin)
+WebKitUserMediaPermissionRequest* webkitUserMediaPermissionRequestCreate(UserMediaPermissionRequestProxy& request, API::SecurityOrigin& userMediaDocumentOrigin, API::SecurityOrigin& topLevelDocumentOrigin)
 {
     WebKitUserMediaPermissionRequest* usermediaPermissionRequest = WEBKIT_USER_MEDIA_PERMISSION_REQUEST(g_object_new(WEBKIT_TYPE_USER_MEDIA_PERMISSION_REQUEST, nullptr));
 
-    // FIXME: store SecurityOrigin
-    UNUSED_PARAM(securityOrigin);
+    // FIXME: store SecurityOrigins
+    UNUSED_PARAM(userMediaDocumentOrigin);
+    UNUSED_PARAM(topLevelDocumentOrigin);
 
     usermediaPermissionRequest->priv->request = &request;
     return usermediaPermissionRequest;
index a729d91..328a161 100644 (file)
@@ -24,6 +24,6 @@
 
 class SecurityOrigin;
 
-WebKitUserMediaPermissionRequest* webkitUserMediaPermissionRequestCreate(WebKit::UserMediaPermissionRequestProxy&, API::SecurityOrigin&);
+WebKitUserMediaPermissionRequest* webkitUserMediaPermissionRequestCreate(WebKit::UserMediaPermissionRequestProxy&, API::SecurityOrigin&, API::SecurityOrigin&);
 
 #endif // WebKitUserMediaPermissionRequestPrivate_h
index 340d88d..7045f5a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2015-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -36,13 +36,13 @@ UserMediaPermissionCheckProxy::UserMediaPermissionCheckProxy(UserMediaPermission
 {
 }
 
-void UserMediaPermissionCheckProxy::setHasPersistentPermission(bool allowed)
+void UserMediaPermissionCheckProxy::setUserMediaAccessInfo(const String& mediaDeviceIdentifierHashSalt, bool allowed)
 {
     ASSERT(m_manager);
     if (!m_manager)
         return;
 
-    m_manager->didCompleteUserMediaPermissionCheck(m_userMediaID, allowed);
+    m_manager->didCompleteUserMediaPermissionCheck(m_userMediaID, mediaDeviceIdentifierHashSalt, allowed);
     m_manager = nullptr;
 }
 
index bb1a0a3..e4b84dc 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2015-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -27,7 +27,6 @@
 #define UserMediaPermissionCheckProxy_h
 
 #include "APIObject.h"
-#include <WebCore/RealtimeMediaSource.h>
 #include <wtf/Vector.h>
 #include <wtf/text/WTFString.h>
 
@@ -42,11 +41,11 @@ public:
         return adoptRef(*new UserMediaPermissionCheckProxy(manager, userMediaID));
     }
 
-    void setHasPersistentPermission(bool allowed);
+    void setUserMediaAccessInfo(const String&, bool allowed);
     void invalidate();
 
 private:
-    UserMediaPermissionCheckProxy(UserMediaPermissionRequestManagerProxy&, uint64_t userMediaID);
+    UserMediaPermissionCheckProxy(UserMediaPermissionRequestManagerProxy&, uint64_t);
 
     UserMediaPermissionRequestManagerProxy* m_manager;
     uint64_t m_userMediaID;
index cde35fa..bd5e951 100644 (file)
@@ -67,7 +67,7 @@ Ref<UserMediaPermissionCheckProxy> UserMediaPermissionRequestManagerProxy::creat
     return request;
 }
 
-void UserMediaPermissionRequestManagerProxy::didCompleteUserMediaPermissionCheck(uint64_t userMediaID, bool allowed)
+void UserMediaPermissionRequestManagerProxy::didCompleteUserMediaPermissionCheck(uint64_t userMediaID, const String& mediaDeviceIdentifierHashSalt, bool allowed)
 {
     if (!m_page.isValid())
         return;
@@ -76,7 +76,7 @@ void UserMediaPermissionRequestManagerProxy::didCompleteUserMediaPermissionCheck
         return;
 
 #if ENABLE(MEDIA_STREAM)
-    m_page.process().send(Messages::WebPage::DidCompleteUserMediaPermissionCheck(userMediaID, allowed), m_page.pageID());
+    m_page.process().send(Messages::WebPage::DidCompleteUserMediaPermissionCheck(userMediaID, mediaDeviceIdentifierHashSalt, allowed), m_page.pageID());
 #else
     UNUSED_PARAM(allowed);
 #endif
index 88d4563..6c22393 100644 (file)
@@ -38,7 +38,7 @@ public:
 
 
     Ref<UserMediaPermissionCheckProxy> createUserMediaPermissionCheck(uint64_t userMediaID);
-    void didCompleteUserMediaPermissionCheck(uint64_t, bool allow);
+    void didCompleteUserMediaPermissionCheck(uint64_t, const String&, bool allow);
 
 private:
     HashMap<uint64_t, RefPtr<UserMediaPermissionRequestProxy>> m_pendingUserMediaRequests;
index 47cd9c2..af8c61c 100644 (file)
@@ -45,9 +45,6 @@ public:
 
     const Vector<String>& videoDeviceUIDs() const { return m_videoDeviceUIDs; }
     const Vector<String>& audioDeviceUIDs() const { return m_audioDeviceUIDs; }
-    
-    const String& firstVideoDeviceUID() const { return !videoDeviceUIDs().isEmpty() ? videoDeviceUIDs().at(0) : emptyString(); }
-    const String& firstAudioDeviceUID() const { return !audioDeviceUIDs().isEmpty() ? audioDeviceUIDs().at(0) : emptyString(); }
 
 private:
     UserMediaPermissionRequestProxy(UserMediaPermissionRequestManagerProxy&, uint64_t userMediaID, const Vector<String>& videoDeviceUIDs, const Vector<String>& audioDeviceUIDs);
index 97467d7..a5ae652 100644 (file)
@@ -5313,28 +5313,45 @@ void WebPageProxy::requestGeolocationPermissionForFrame(uint64_t geolocationID,
     request->deny();
 }
 
-void WebPageProxy::requestUserMediaPermissionForFrame(uint64_t userMediaID, uint64_t frameID, String originIdentifier, const Vector<String>& audioDeviceUIDs, const Vector<String>& videoDeviceUIDs)
+void WebPageProxy::requestUserMediaPermissionForFrame(uint64_t userMediaID, uint64_t frameID, String userMediaDocumentOriginIdentifier, String topLevelDocumentOriginIdentifier, const Vector<String>& audioDeviceUIDs, const Vector<String>& videoDeviceUIDs)
 {
+#if ENABLE(MEDIA_STREAM)
     WebFrameProxy* frame = m_process->webFrame(frameID);
     MESSAGE_CHECK(frame);
 
-    RefPtr<API::SecurityOrigin> origin = API::SecurityOrigin::create(SecurityOrigin::createFromDatabaseIdentifier(originIdentifier));
+    RefPtr<API::SecurityOrigin> userMediaOrigin = API::SecurityOrigin::create(SecurityOrigin::createFromDatabaseIdentifier(userMediaDocumentOriginIdentifier));
+    RefPtr<API::SecurityOrigin> topLevelOrigin = API::SecurityOrigin::create(SecurityOrigin::createFromDatabaseIdentifier(topLevelDocumentOriginIdentifier));
     RefPtr<UserMediaPermissionRequestProxy> request = m_userMediaPermissionRequestManager.createRequest(userMediaID, audioDeviceUIDs, videoDeviceUIDs);
 
-    if (!m_uiClient->decidePolicyForUserMediaPermissionRequest(*this, *frame, *origin.get(), *request.get()))
+    if (!m_uiClient->decidePolicyForUserMediaPermissionRequest(*this, *frame, *userMediaOrigin.get(), *topLevelOrigin.get(), *request.get()))
         request->deny();
+#else
+    UNUSED_PARAM(userMediaID);
+    UNUSED_PARAM(frameID);
+    UNUSED_PARAM(userMediaDocumentOriginIdentifier);
+    UNUSED_PARAM(topLevelDocumentOriginIdentifier);
+    UNUSED_PARAM(audioDeviceUIDs);
+    UNUSED_PARAM(videoDeviceUIDs);
+#endif
 }
 
-void WebPageProxy::checkUserMediaPermissionForFrame(uint64_t userMediaID, uint64_t frameID, String originIdentifier)
+void WebPageProxy::checkUserMediaPermissionForFrame(uint64_t userMediaID, uint64_t frameID, String userMediaDocumentOriginIdentifier, String topLevelDocumentOriginIdentifier)
 {
+#if ENABLE(MEDIA_STREAM)
     WebFrameProxy* frame = m_process->webFrame(frameID);
     MESSAGE_CHECK(frame);
 
-    RefPtr<API::SecurityOrigin> origin = API::SecurityOrigin::create(SecurityOrigin::createFromDatabaseIdentifier(originIdentifier));
     RefPtr<UserMediaPermissionCheckProxy> request = m_userMediaPermissionRequestManager.createUserMediaPermissionCheck(userMediaID);
-
-    if (!m_uiClient->checkUserMediaPermissionForOrigin(*this, *frame, *origin.get(), *request.get()))
-        request->setHasPersistentPermission(false);
+    RefPtr<API::SecurityOrigin> userMediaOrigin = API::SecurityOrigin::create(SecurityOrigin::createFromDatabaseIdentifier(userMediaDocumentOriginIdentifier));
+    RefPtr<API::SecurityOrigin> topLevelOrigin = API::SecurityOrigin::create(SecurityOrigin::createFromDatabaseIdentifier(topLevelDocumentOriginIdentifier));
+    if (!m_uiClient->checkUserMediaPermissionForOrigin(*this, *frame, *userMediaOrigin.get(), *topLevelOrigin.get(), *request.get()))
+        request->setUserMediaAccessInfo(emptyString(), false);
+#else
+    UNUSED_PARAM(userMediaID);
+    UNUSED_PARAM(frameID);
+    UNUSED_PARAM(userMediaDocumentOriginIdentifier);
+    UNUSED_PARAM(topLevelDocumentOriginIdentifier);
+#endif
 }
 
 void WebPageProxy::requestNotificationPermission(uint64_t requestID, const String& originString)
index f23194e..aea2495 100644 (file)
@@ -157,7 +157,6 @@ class DragData;
 class FloatRect;
 class GraphicsLayer;
 class IntSize;
-class MediaConstraintsImpl;
 class ProtectionSpace;
 class RunLoopObserver;
 class SharedBuffer;
@@ -1207,8 +1206,8 @@ private:
     void reachedApplicationCacheOriginQuota(const String& originIdentifier, uint64_t currentQuota, uint64_t totalBytesNeeded, PassRefPtr<Messages::WebPageProxy::ReachedApplicationCacheOriginQuota::DelayedReply>);
     void requestGeolocationPermissionForFrame(uint64_t geolocationID, uint64_t frameID, String originIdentifier);
 
-    void requestUserMediaPermissionForFrame(uint64_t userMediaID, uint64_t frameID, String originIdentifier, const Vector<String>& audioDeviceUIDs, const Vector<String>& videoDeviceUIDs);
-    void checkUserMediaPermissionForFrame(uint64_t userMediaID, uint64_t frameID, String originIdentifier);
+    void requestUserMediaPermissionForFrame(uint64_t userMediaID, uint64_t frameID, String userMediaDocumentOriginIdentifier, String topLevelDocumentOriginIdentifier, const Vector<String>& audioDeviceUIDs, const Vector<String>& videoDeviceUIDs);
+    void checkUserMediaPermissionForFrame(uint64_t userMediaID, uint64_t frameID, String userMediaDocumentOriginIdentifier, String topLevelDocumentOriginIdentifier);
 
     void runModal();
     void notifyScrollerThumbIsVisibleInRect(const WebCore::IntRect&);
index 92eb56a..14e50f9 100644 (file)
@@ -264,8 +264,8 @@ messages -> WebPageProxy {
     
 #if ENABLE(MEDIA_STREAM)
     # MediaSteam messages
-    RequestUserMediaPermissionForFrame(uint64_t userMediaID, uint64_t frameID, String originIdentifier, Vector<String> audioDeviceUIDs, Vector<String> videoDeviceUIDs)
-    CheckUserMediaPermissionForFrame(uint64_t userMediaID, uint64_t frameID, String originIdentifier)
+    RequestUserMediaPermissionForFrame(uint64_t userMediaID, uint64_t frameID, String userMediaDocumentOriginIdentifier, String topLevelDocumentOriginIdentifier, Vector<String> audioDeviceUIDs, Vector<String> videoDeviceUIDs)
+    CheckUserMediaPermissionForFrame(uint64_t userMediaID, uint64_t frameID, String userMediaDocumentOriginIdentifier, String topLevelDocumentOriginIdentifier)
 #endif
 
     # Notification messages
index 88a62d8..d4a3efe 100644 (file)
@@ -59,6 +59,8 @@
                07297FA21C186ADB003F0735 /* WKUserMediaPermissionCheck.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 07297FA01C186ADB003F0735 /* WKUserMediaPermissionCheck.cpp */; };
                07297FA31C186ADB003F0735 /* WKUserMediaPermissionCheck.h in Headers */ = {isa = PBXBuildFile; fileRef = 07297FA11C186ADB003F0735 /* WKUserMediaPermissionCheck.h */; settings = {ATTRIBUTES = (Private, ); }; };
                076E884E1A13CADF005E90FC /* APIContextMenuClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 076E884D1A13CADF005E90FC /* APIContextMenuClient.h */; };
+               07A5EBBB1C7BA43E00B9CA69 /* WKFrameHandleRef.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 07A5EBB91C7BA43E00B9CA69 /* WKFrameHandleRef.cpp */; };
+               07A5EBBC1C7BA43E00B9CA69 /* WKFrameHandleRef.h in Headers */ = {isa = PBXBuildFile; fileRef = 07A5EBBA1C7BA43E00B9CA69 /* WKFrameHandleRef.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F0C365818C051BA00F607D7 /* RemoteLayerTreeHostIOS.mm in Sources */ = {isa = PBXBuildFile; fileRef = 0F0C365718C051BA00F607D7 /* RemoteLayerTreeHostIOS.mm */; };
                0F0C365A18C0555800F607D7 /* LayerRepresentation.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F0C365918C0555800F607D7 /* LayerRepresentation.h */; };
                0F0C365C18C05CA100F607D7 /* RemoteScrollingCoordinatorProxyIOS.mm in Sources */ = {isa = PBXBuildFile; fileRef = 0F0C365B18C05CA100F607D7 /* RemoteScrollingCoordinatorProxyIOS.mm */; };
                07297FA11C186ADB003F0735 /* WKUserMediaPermissionCheck.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKUserMediaPermissionCheck.h; sourceTree = "<group>"; };
                076E884D1A13CADF005E90FC /* APIContextMenuClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = APIContextMenuClient.h; sourceTree = "<group>"; };
                076E884F1A13CBC6005E90FC /* APIInjectedBundlePageContextMenuClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = APIInjectedBundlePageContextMenuClient.h; sourceTree = "<group>"; };
+               07A5EBB91C7BA43E00B9CA69 /* WKFrameHandleRef.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WKFrameHandleRef.cpp; sourceTree = "<group>"; };
+               07A5EBBA1C7BA43E00B9CA69 /* WKFrameHandleRef.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKFrameHandleRef.h; sourceTree = "<group>"; };
                0867D6A5FE840307C02AAC07 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = "<absolute>"; };
                089C1667FE841158C02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = "<group>"; };
                0F0C365718C051BA00F607D7 /* RemoteLayerTreeHostIOS.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = RemoteLayerTreeHostIOS.mm; path = ios/RemoteLayerTreeHostIOS.mm; sourceTree = "<group>"; };
                                BCE469581214EDF4000B98EB /* WKFormSubmissionListener.h */,
                                BCD01398110FA420003B8A67 /* WKFrame.cpp */,
                                BCD01397110FA420003B8A67 /* WKFrame.h */,
+                               07A5EBB91C7BA43E00B9CA69 /* WKFrameHandleRef.cpp */,
+                               07A5EBBA1C7BA43E00B9CA69 /* WKFrameHandleRef.h */,
                                2D3A65E41A7C3AA700CAC637 /* WKFrameInfoRef.cpp */,
                                2D3A65E51A7C3AA700CAC637 /* WKFrameInfoRef.h */,
                                BCB9F6A41123DD0D00A137E0 /* WKFramePolicyListener.cpp */,
                                1A5704F21BE0174000874AF1 /* _WKElementInfo.h in Headers */,
                                1AD01BC91905D37E00C9C45F /* _WKErrorRecoveryAttempting.h in Headers */,
                                005D158F18E4C4EB00734619 /* _WKFindDelegate.h in Headers */,
+                               07A5EBBC1C7BA43E00B9CA69 /* WKFrameHandleRef.h in Headers */,
                                510523741C73D38B007993CB /* WebIDBConnectionToServerMessages.h in Headers */,
                                2DEAC5CF1AC368BB00A195D8 /* _WKFindOptions.h in Headers */,
                                2E7A944A1BBD97C300945547 /* _WKFocusedElementInfo.h in Headers */,
                                1AAF089A19267EE500B6390C /* WKUserScript.mm in Sources */,
                                7C89D2A31A678875003A5FDE /* WKUserScriptRef.cpp in Sources */,
                                BC8699B6116AADAA002A925B /* WKView.mm in Sources */,
+                               07A5EBBB1C7BA43E00B9CA69 /* WKFrameHandleRef.cpp in Sources */,
                                2D28A4981AF965A200F190C9 /* WKViewLayoutStrategy.mm in Sources */,
                                C5E1AFE816B20B67006CC1F2 /* WKWebArchive.cpp in Sources */,
                                C5E1AFEA16B20B7B006CC1F2 /* WKWebArchiveResource.cpp in Sources */,
index 307b60e..73ecadc 100644 (file)
@@ -62,8 +62,9 @@ void UserMediaPermissionRequestManager::startUserMediaRequest(UserMediaRequest&
     WebFrame* webFrame = WebFrame::fromCoreFrame(*frame);
     ASSERT(webFrame);
 
-    SecurityOrigin* origin = request.securityOrigin();
-    m_page.send(Messages::WebPageProxy::RequestUserMediaPermissionForFrame(requestID, webFrame->frameID(), origin->databaseIdentifier(), request.audioDeviceUIDs(), request.videoDeviceUIDs()));
+    SecurityOrigin* topLevelDocumentOrigin = request.topLevelDocumentOrigin();
+    String topLevelDocumentOriginString = topLevelDocumentOrigin ? topLevelDocumentOrigin->databaseIdentifier() : emptyString();
+    m_page.send(Messages::WebPageProxy::RequestUserMediaPermissionForFrame(requestID, webFrame->frameID(), request.userMediaDocumentOrigin()->databaseIdentifier(), topLevelDocumentOriginString, request.audioDeviceUIDs(), request.videoDeviceUIDs()));
 }
 
 void UserMediaPermissionRequestManager::cancelUserMediaRequest(UserMediaRequest& request)
@@ -93,7 +94,7 @@ void UserMediaPermissionRequestManager::startUserMediaPermissionCheck(WebCore::U
     Frame* frame = document ? document->frame() : nullptr;
 
     if (!frame) {
-        request.setHasPersistentPermission(false);
+        request.setUserMediaAccessInfo(emptyString(), false);
         return;
     }
 
@@ -104,8 +105,9 @@ void UserMediaPermissionRequestManager::startUserMediaPermissionCheck(WebCore::U
     WebFrame* webFrame = WebFrame::fromCoreFrame(*frame);
     ASSERT(webFrame);
 
-    SecurityOrigin* origin = request.securityOrigin();
-    m_page.send(Messages::WebPageProxy::CheckUserMediaPermissionForFrame(requestID, webFrame->frameID(), origin->databaseIdentifier()));
+    SecurityOrigin* topLevelDocumentOrigin = request.topLevelDocumentOrigin();
+    String topLevelDocumentOriginString = topLevelDocumentOrigin ? topLevelDocumentOrigin->databaseIdentifier() : emptyString();
+    m_page.send(Messages::WebPageProxy::CheckUserMediaPermissionForFrame(requestID, webFrame->frameID(), request.userMediaDocumentOrigin()->databaseIdentifier(), topLevelDocumentOriginString));
 }
 
 void UserMediaPermissionRequestManager::cancelUserMediaPermissionCheck(WebCore::UserMediaPermissionCheck& request)
@@ -116,14 +118,14 @@ void UserMediaPermissionRequestManager::cancelUserMediaPermissionCheck(WebCore::
     m_idToUserMediaPermissionCheckMap.remove(requestID);
 }
 
-void UserMediaPermissionRequestManager::didCompleteUserMediaPermissionCheck(uint64_t requestID, bool allowed)
+void UserMediaPermissionRequestManager::didCompleteUserMediaPermissionCheck(uint64_t requestID, const String& mediaDeviceIdentifierHashSalt, bool allowed)
 {
     RefPtr<UserMediaPermissionCheck> request = m_idToUserMediaPermissionCheckMap.take(requestID);
     if (!request)
         return;
     m_userMediaPermissionCheckToIDMap.remove(request);
     
-    request->setHasPersistentPermission(allowed);
+    request->setUserMediaAccessInfo(mediaDeviceIdentifierHashSalt, allowed);
 }
 
 } // namespace WebKit
index a0b3490..12d7a6d 100644 (file)
@@ -41,7 +41,7 @@ public:
 
     void startUserMediaPermissionCheck(WebCore::UserMediaPermissionCheck&);
     void cancelUserMediaPermissionCheck(WebCore::UserMediaPermissionCheck&);
-    void didCompleteUserMediaPermissionCheck(uint64_t requestID, bool allowed);
+    void didCompleteUserMediaPermissionCheck(uint64_t requestID, const String&, bool allowed);
 
 private:
     WebPage& m_page;
index f06199b..29edf98 100644 (file)
@@ -3476,9 +3476,9 @@ void WebPage::didReceiveUserMediaPermissionDecision(uint64_t userMediaID, bool a
     m_userMediaPermissionRequestManager.didReceiveUserMediaPermissionDecision(userMediaID, allowed, audioDeviceUID, videoDeviceUID);
 }
 
-void WebPage::didCompleteUserMediaPermissionCheck(uint64_t userMediaID, bool allowed)
+void WebPage::didCompleteUserMediaPermissionCheck(uint64_t userMediaID, const String& mediaDeviceIdentifierHashSalt, bool allowed)
 {
-    m_userMediaPermissionRequestManager.didCompleteUserMediaPermissionCheck(userMediaID, allowed);
+    m_userMediaPermissionRequestManager.didCompleteUserMediaPermissionCheck(userMediaID, mediaDeviceIdentifierHashSalt, allowed);
 }
 #endif
 
index 8aeb6fd..40a4e00 100644 (file)
@@ -1111,7 +1111,7 @@ private:
 
 #if ENABLE(MEDIA_STREAM)
     void didReceiveUserMediaPermissionDecision(uint64_t userMediaID, bool allowed, const String& audioDeviceUID, const String& videoDeviceUID);
-    void didCompleteUserMediaPermissionCheck(uint64_t userMediaID, bool allowed);
+    void didCompleteUserMediaPermissionCheck(uint64_t userMediaID, const String&, bool allowed);
 #endif
 
     void advanceToNextMisspelling(bool startBeforeSelection);
index de86c9a..90e8102 100644 (file)
@@ -283,7 +283,7 @@ messages -> WebPage LegacyReceiver {
 #if ENABLE(MEDIA_STREAM)
     # MediaSteam
     DidReceiveUserMediaPermissionDecision(uint64_t userMediaID, bool allowed, String audioDeviceUID, String videoDeviceUID)
-    DidCompleteUserMediaPermissionCheck(uint64_t userMediaID, bool allowed)
+    DidCompleteUserMediaPermissionCheck(uint64_t userMediaID, String mediaDeviceIdentifierHashSalt, bool allowed)
 #endif
 
     # Notification
index ea044a2..bfa8d89 100644 (file)
@@ -1,3 +1,41 @@
+2016-02-25  Eric Carlson  <eric.carlson@apple.com>
+
+        [MediaStream] MediaDeviceInfo deviceId and groupId must be unique to the page's origin
+        https://bugs.webkit.org/show_bug.cgi?id=153163
+        <rdar://problem/24334526>
+
+        Reviewed by Tim Horton.
+
+        * WebKitTestRunner/InjectedBundle/InjectedBundle.cpp:
+        (WTR::InjectedBundle::setUserMediaPermissionForOrigin): Take top level document origin.
+        * WebKitTestRunner/InjectedBundle/InjectedBundle.h:
+
+        * WebKitTestRunner/InjectedBundle/TestRunner.cpp:
+        (WTR::TestRunner::setUserMediaPermissionForOrigin): Ditto.
+        * WebKitTestRunner/InjectedBundle/TestRunner.h:
+
+        * WebKitTestRunner/TestController.cpp:
+        (WTR::decidePolicyForUserMediaPermissionRequest): Pass through top level document origin.
+        (WTR::checkUserMediaPermissionForOrigin): Ditto.
+        (WTR::TestController::resetStateToConsistentValues): m_userMediaOriginPermissions -> m_cahcedUserMediaPermissions.
+        (WTR::originUserVisibleName): Return a String.
+        (WTR::userMediaOriginHash): Create a hash of the origin plus top level document origin.
+        (WTR::TestController::saltForOrigin): Return salt for an origin.
+        (WTR::TestController::setUserMediaPermissionForOrigin): Return permission for an origin.
+        (WTR::TestController::handleCheckOfUserMediaPermissionForOrigin):
+        (WTR::TestController::handleUserMediaPermissionRequest):
+        (WTR::TestController::decidePolicyForUserMediaPermissionRequestIfPossible):
+        (WTR::OriginSettings::OriginSettings): New, class to cache settings for an origin.
+        (WTR::OriginSettings::persistentPermission): Persistent permissions for origin.
+        (WTR::OriginSettings::setPersistentPermission): Set permissions for origin.
+        (WTR::OriginSettings::persistentSalt): Return the persistent salt for the origin, if any.
+        (WTR::OriginSettings::setPersistentSalt): Set the persistent salt for the origin
+        (WTR::OriginSettings::ephemeralSalts): Return hashmap used to store per-frame salts.
+        * WebKitTestRunner/TestController.h:
+
+        * WebKitTestRunner/TestInvocation.cpp:
+        (WTR::TestInvocation::didReceiveMessageFromInjectedBundle):
+
 2016-02-24  Nikos Andronikos  <nikos.andronikos-webkit@cisra.canon.com.au>
 
         [web-animations] Add AnimationTimeline, DocumentTimeline and add extensions to Document interface
index a86202b..f9b6497 100644 (file)
@@ -179,7 +179,7 @@ interface TestRunner {
 
     // MediaStream
     void setUserMediaPermission(boolean value);
-    void setUserMediaPermissionForOrigin(boolean permission, DOMString url);
+    void setUserMediaPermissionForOrigin(boolean permission, DOMString origin, DOMString parentOrigin);
 
     // Audio testing.
     [PassContext] void setAudioResult(object data);
index 72c0458..41fb85d 100644 (file)
@@ -526,7 +526,7 @@ void InjectedBundle::setUserMediaPermission(bool enabled)
     WKBundlePagePostMessage(page()->page(), messageName.get(), messageBody.get());
 }
 
-void InjectedBundle::setUserMediaPermissionForOrigin(bool permission, WKStringRef url)
+void InjectedBundle::setUserMediaPermissionForOrigin(bool permission, WKStringRef origin, WKStringRef parentOrigin)
 {
     auto messageName = adoptWK(WKStringCreateWithUTF8CString("SetUserMediaPermissionForOrigin"));
     WKRetainPtr<WKMutableDictionaryRef> messageBody(AdoptWK, WKMutableDictionaryCreate());
@@ -535,8 +535,11 @@ void InjectedBundle::setUserMediaPermissionForOrigin(bool permission, WKStringRe
     WKRetainPtr<WKBooleanRef> permissionWK(AdoptWK, WKBooleanCreate(permission));
     WKDictionarySetItem(messageBody.get(), permissionKeyWK.get(), permissionWK.get());
 
-    WKRetainPtr<WKStringRef> urlKeyWK(AdoptWK, WKStringCreateWithUTF8CString("url"));
-    WKDictionarySetItem(messageBody.get(), urlKeyWK.get(), url);
+    WKRetainPtr<WKStringRef> originKeyWK(AdoptWK, WKStringCreateWithUTF8CString("origin"));
+    WKDictionarySetItem(messageBody.get(), originKeyWK.get(), origin);
+
+    WKRetainPtr<WKStringRef> parentOriginKeyWK(AdoptWK, WKStringCreateWithUTF8CString("parentOrigin"));
+    WKDictionarySetItem(messageBody.get(), parentOriginKeyWK.get(), parentOrigin);
 
     WKBundlePagePostMessage(page()->page(), messageName.get(), messageBody.get());
 }
index 0f0e1f1..9c3438e 100644 (file)
@@ -96,7 +96,7 @@ public:
 
     // MediaStream.
     void setUserMediaPermission(bool);
-    void setUserMediaPermissionForOrigin(bool permission, WKStringRef url);
+    void setUserMediaPermissionForOrigin(bool permission, WKStringRef origin, WKStringRef parentOrigin);
 
     // Policy delegate.
     void setCustomPolicyDelegate(bool enabled, bool permissive);
index e3f8f56..965a344 100644 (file)
@@ -775,10 +775,11 @@ void TestRunner::setUserMediaPermission(bool enabled)
     InjectedBundle::singleton().setUserMediaPermission(enabled);
 }
 
-void TestRunner::setUserMediaPermissionForOrigin(bool permission, JSStringRef url)
+void TestRunner::setUserMediaPermissionForOrigin(bool permission, JSStringRef origin, JSStringRef parentOrigin)
 {
-    WKRetainPtr<WKStringRef> urlWK = toWK(url);
-    InjectedBundle::singleton().setUserMediaPermissionForOrigin(permission, urlWK.get());
+    WKRetainPtr<WKStringRef> originWK = toWK(origin);
+    WKRetainPtr<WKStringRef> parentOriginWK = toWK(parentOrigin);
+    InjectedBundle::singleton().setUserMediaPermissionForOrigin(permission, originWK.get(), parentOriginWK.get());
 }
 
 bool TestRunner::callShouldCloseOnWebView()
index 67c5c6c..809e3f9 100644 (file)
@@ -268,7 +268,7 @@ public:
 
     // MediaStream
     void setUserMediaPermission(bool);
-    void setUserMediaPermissionForOrigin(bool permission, JSStringRef url);
+    void setUserMediaPermissionForOrigin(bool permission, JSStringRef origin, JSStringRef parentOrigin);
 
     void setPageVisibility(JSStringRef state);
     void resetPageVisibility();
index f303c8e..ddad44f 100644 (file)
@@ -31,6 +31,7 @@
 #include "PlatformWebView.h"
 #include "StringFunctions.h"
 #include "TestInvocation.h"
+#include <WebCore/UUID.h>
 #include <WebKit/WKArray.h>
 #include <WebKit/WKAuthenticationChallenge.h>
 #include <WebKit/WKAuthenticationDecisionListener.h>
@@ -38,6 +39,8 @@
 #include <WebKit/WKContextPrivate.h>
 #include <WebKit/WKCookieManager.h>
 #include <WebKit/WKCredential.h>
+#include <WebKit/WKFrameHandleRef.h>
+#include <WebKit/WKFrameInfoRef.h>
 #include <WebKit/WKIconDatabase.h>
 #include <WebKit/WKNavigationResponseRef.h>
 #include <WebKit/WKNotification.h>
 #include <stdlib.h>
 #include <string>
 #include <unistd.h>
+#include <wtf/CryptographicallyRandomNumber.h>
+#include <wtf/HexNumber.h>
 #include <wtf/MainThread.h>
+#include <wtf/RefCounted.h>
 #include <wtf/RunLoop.h>
 #include <wtf/TemporaryChange.h>
 #include <wtf/text/CString.h>
@@ -203,14 +209,14 @@ static void decidePolicyForGeolocationPermissionRequest(WKPageRef, WKFrameRef, W
     TestController::singleton().handleGeolocationPermissionRequest(permissionRequest);
 }
 
-static void decidePolicyForUserMediaPermissionRequest(WKPageRef, WKFrameRef, WKSecurityOriginRef origin, WKUserMediaPermissionRequestRef permissionRequest, const void* clientInfo)
+static void decidePolicyForUserMediaPermissionRequest(WKPageRef, WKFrameRef frame, WKSecurityOriginRef userMediaDocumentOrigin, WKSecurityOriginRef topLevelDocumentOrigin, WKUserMediaPermissionRequestRef permissionRequest, const void* clientInfo)
 {
-    TestController::singleton().handleUserMediaPermissionRequest(origin, permissionRequest);
+    TestController::singleton().handleUserMediaPermissionRequest(frame, userMediaDocumentOrigin, topLevelDocumentOrigin, permissionRequest);
 }
 
-static void checkUserMediaPermissionForOrigin(WKPageRef, WKFrameRef, WKSecurityOriginRef origin, WKUserMediaPermissionCheckRef checkRequest, const void*)
+static void checkUserMediaPermissionForOrigin(WKPageRef, WKFrameRef frame, WKSecurityOriginRef userMediaDocumentOrigin, WKSecurityOriginRef topLevelDocumentOrigin, WKUserMediaPermissionCheckRef checkRequest, const void*)
 {
-    TestController::singleton().handleCheckOfUserMediaPermissionForOrigin(origin, checkRequest);
+    TestController::singleton().handleCheckOfUserMediaPermissionForOrigin(frame, userMediaDocumentOrigin, topLevelDocumentOrigin, checkRequest);
 }
 
 WKPageRef TestController::createOtherPage(WKPageRef oldPage, WKPageConfigurationRef configuration, WKNavigationActionRef navigationAction, WKWindowFeaturesRef windowFeatures, const void *clientInfo)
@@ -756,7 +762,7 @@ bool TestController::resetStateToConsistentValues()
 
     // Reset UserMedia permissions.
     m_userMediaPermissionRequests.clear();
-    m_userMediaOriginPermissions = nullptr;
+    m_cahcedUserMediaPermissions.clear();
     m_isUserMediaPermissionSet = false;
     m_isUserMediaPermissionAllowed = false;
 
@@ -1676,19 +1682,43 @@ bool TestController::isGeolocationProviderActive() const
     return m_geolocationProvider->isActive();
 }
 
-static WKStringRef originUserVisibleName(WKSecurityOriginRef origin)
+static String originUserVisibleName(WKSecurityOriginRef origin)
 {
+    if (!origin)
+        return emptyString();
+
     std::string host = toSTD(adoptWK(WKSecurityOriginCopyHost(origin))).c_str();
     std::string protocol = toSTD(adoptWK(WKSecurityOriginCopyProtocol(origin))).c_str();
-    unsigned short port = WKSecurityOriginGetPort(origin);
 
-    String userVisibleName;
+    if (!host.length() || !protocol.length())
+        return emptyString();
+
+    unsigned short port = WKSecurityOriginGetPort(origin);
     if (port)
-        userVisibleName = String::format("%s://%s:%d", protocol.c_str(), host.c_str(), port);
-    else
-        userVisibleName = String::format("%s://%s", protocol.c_str(), host.c_str());
+        return String::format("%s://%s:%d", protocol.c_str(), host.c_str(), port);
+
+    return String::format("%s://%s", protocol.c_str(), host.c_str());
+}
+
+static String userMediaOriginHash(WKSecurityOriginRef userMediaDocumentOrigin, WKSecurityOriginRef topLevelDocumentOrigin)
+{
+    String userMediaDocumentOriginString = originUserVisibleName(userMediaDocumentOrigin);
+    String topLevelDocumentOriginString = originUserVisibleName(topLevelDocumentOrigin);
+
+    if (topLevelDocumentOriginString.isEmpty())
+        return userMediaDocumentOriginString;
 
-    return WKStringCreateWithUTF8CString(userVisibleName.utf8().data());
+    return String::format("%s-%s", userMediaDocumentOriginString.utf8().data(), topLevelDocumentOriginString.utf8().data());
+}
+
+static String userMediaOriginHash(WKStringRef userMediaDocumentOriginString, WKStringRef topLevelDocumentOriginString)
+{
+    auto userMediaDocumentOrigin = adoptWK(WKSecurityOriginCreateFromString(userMediaDocumentOriginString));
+    if (!WKStringGetLength(topLevelDocumentOriginString))
+        return userMediaOriginHash(userMediaDocumentOrigin.get(), nullptr);
+
+    auto topLevelDocumentOrigin = adoptWK(WKSecurityOriginCreateFromString(topLevelDocumentOriginString));
+    return userMediaOriginHash(userMediaDocumentOrigin.get(), topLevelDocumentOrigin.get());
 }
 
 void TestController::setUserMediaPermission(bool enabled)
@@ -1698,32 +1728,82 @@ void TestController::setUserMediaPermission(bool enabled)
     decidePolicyForUserMediaPermissionRequestIfPossible();
 }
 
-void TestController::setUserMediaPermissionForOrigin(bool permission, WKStringRef originString)
+class OriginSettings : public RefCounted<OriginSettings> {
+public:
+    explicit OriginSettings()
+    {
+    }
+
+    bool persistentPermission() const { return m_persistentPermission; }
+    void setPersistentPermission(bool permission) { m_persistentPermission = permission; }
+
+    String persistentSalt() const { return m_persistentSalt; }
+    void setPersistentSalt(const String& salt) { m_persistentSalt = salt; }
+
+    HashMap<uint64_t, String>& ephemeralSalts() { return m_ephemeralSalts; }
+
+private:
+    HashMap<uint64_t, String> m_ephemeralSalts;
+    String m_persistentSalt;
+    bool m_persistentPermission { false };
+};
+
+String TestController::saltForOrigin(WKFrameRef frame, String originHash)
 {
-    if (!m_userMediaOriginPermissions)
-        m_userMediaOriginPermissions = adoptWK(WKMutableDictionaryCreate());
-    WKRetainPtr<WKBooleanRef> allowed = adoptWK(WKBooleanCreate(permission));
-    WKRetainPtr<WKSecurityOriginRef> origin = adoptWK(WKSecurityOriginCreateFromString(originString));
-    WKDictionarySetItem(m_userMediaOriginPermissions.get(), originUserVisibleName(origin.get()), allowed.get());
+    RefPtr<OriginSettings> settings = m_cahcedUserMediaPermissions.get(originHash);
+    if (!settings) {
+        settings = adoptRef(*new OriginSettings());
+        m_cahcedUserMediaPermissions.add(originHash, settings);
+    }
+
+    auto& ephemeralSalts = settings->ephemeralSalts();
+    auto frameInfo = adoptWK(WKFrameCreateFrameInfo(frame));
+    auto frameHandle = WKFrameInfoGetFrameHandleRef(frameInfo.get());
+    uint64_t frameIdentifier = WKFrameHandleGetFrameID(frameHandle);
+    String frameSalt = ephemeralSalts.get(frameIdentifier);
+
+    if (settings->persistentPermission()) {
+        if (frameSalt.length())
+            return frameSalt;
+
+        if (!settings->persistentSalt().length())
+            settings->setPersistentSalt(WebCore::createCanonicalUUIDString());
+
+        return settings->persistentSalt();
+    }
+
+    if (!frameSalt.length()) {
+        frameSalt = WebCore::createCanonicalUUIDString();
+        ephemeralSalts.add(frameIdentifier, frameSalt);
+    }
+
+    return frameSalt;
 }
 
-void TestController::handleCheckOfUserMediaPermissionForOrigin(WKSecurityOriginRef origin, const WKUserMediaPermissionCheckRef& checkRequest)
+void TestController::setUserMediaPermissionForOrigin(bool permission, WKStringRef userMediaDocumentOriginString, WKStringRef topLevelDocumentOriginString)
 {
-    bool allowed = false;
-
-    if (m_userMediaOriginPermissions) {
-        WKRetainPtr<WKStringRef> originString = originUserVisibleName(origin);
-        WKBooleanRef value = static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(m_userMediaOriginPermissions.get(), originString.get()));
-        if (value && WKGetTypeID(value) == WKBooleanGetTypeID())
-            allowed = WKBooleanGetValue(value);
+    auto originHash = userMediaOriginHash(userMediaDocumentOriginString, topLevelDocumentOriginString);
+    RefPtr<OriginSettings> settings = m_cahcedUserMediaPermissions.get(originHash);
+    if (!settings) {
+        settings = adoptRef(*new OriginSettings());
+        m_cahcedUserMediaPermissions.add(originHash, settings);
     }
 
-    WKUserMediaPermissionCheckSetHasPersistentPermission(checkRequest, allowed);
+    settings->setPersistentPermission(permission);
+}
+
+void TestController::handleCheckOfUserMediaPermissionForOrigin(WKFrameRef frame, WKSecurityOriginRef userMediaDocumentOrigin, WKSecurityOriginRef topLevelDocumentOrigin, const WKUserMediaPermissionCheckRef& checkRequest)
+{
+    auto originHash = userMediaOriginHash(userMediaDocumentOrigin, topLevelDocumentOrigin);
+    auto salt = saltForOrigin(frame, originHash);
+
+    WKUserMediaPermissionCheckSetUserMediaAccessInfo(checkRequest, WKStringCreateWithUTF8CString(salt.utf8().data()), m_cahcedUserMediaPermissions.get(originHash)->persistentPermission());
 }
 
-void TestController::handleUserMediaPermissionRequest(WKSecurityOriginRef origin, WKUserMediaPermissionRequestRef request)
+void TestController::handleUserMediaPermissionRequest(WKFrameRef frame, WKSecurityOriginRef userMediaDocumentOrigin, WKSecurityOriginRef topLevelDocumentOrigin, WKUserMediaPermissionRequestRef request)
 {
-    m_userMediaPermissionRequests.append(std::make_pair(origin, request));
+    auto originHash = userMediaOriginHash(userMediaDocumentOrigin, topLevelDocumentOrigin);
+    m_userMediaPermissionRequests.append(std::make_pair(originHash, request));
     decidePolicyForUserMediaPermissionRequestIfPossible();
 }
 
@@ -1733,11 +1813,18 @@ void TestController::decidePolicyForUserMediaPermissionRequestIfPossible()
         return;
 
     for (auto& pair : m_userMediaPermissionRequests) {
+        auto originHash = pair.first;
         auto request = pair.second.get();
+
+        bool persistentPermission = false;
+        RefPtr<OriginSettings> settings = m_cahcedUserMediaPermissions.get(originHash);
+        if (settings)
+            persistentPermission = settings->persistentPermission();
+
         WKRetainPtr<WKArrayRef> audioDeviceUIDs = WKUserMediaPermissionRequestAudioDeviceUIDs(request);
         WKRetainPtr<WKArrayRef> videoDeviceUIDs = WKUserMediaPermissionRequestVideoDeviceUIDs(request);
 
-        if (m_isUserMediaPermissionAllowed && (WKArrayGetSize(videoDeviceUIDs.get()) || WKArrayGetSize(audioDeviceUIDs.get()))) {
+        if ((m_isUserMediaPermissionAllowed || persistentPermission) && (WKArrayGetSize(videoDeviceUIDs.get()) || WKArrayGetSize(audioDeviceUIDs.get()))) {
             WKRetainPtr<WKStringRef> videoDeviceUID;
             if (WKArrayGetSize(videoDeviceUIDs.get()))
                 videoDeviceUID = reinterpret_cast<WKStringRef>(WKArrayGetItemAtIndex(videoDeviceUIDs.get(), 0));
index 3822b3e..d51caf7 100644 (file)
 #include <vector>
 #include <wtf/HashMap.h>
 #include <wtf/Vector.h>
+#include <wtf/text/StringHash.h>
 
 OBJC_CLASS WKWebViewConfiguration;
 
 namespace WTR {
 
 class TestInvocation;
+class OriginSettings;
 class PlatformWebView;
 class EventSenderProxy;
 struct TestOptions;
@@ -95,10 +97,13 @@ public:
     bool isGeolocationProviderActive() const;
 
     // MediaStream.
+    String saltForOrigin(WKFrameRef, String);
+    void getUserMediaInfoForOrigin(WKFrameRef, WKStringRef originKey, bool&, WKRetainPtr<WKStringRef>&);
+    WKStringRef getUserMediaSaltForOrigin(WKFrameRef, WKStringRef originKey);
     void setUserMediaPermission(bool);
-    void setUserMediaPermissionForOrigin(bool permission, WKStringRef url);
-    void handleUserMediaPermissionRequest(WKSecurityOriginRef, WKUserMediaPermissionRequestRef);
-    void handleCheckOfUserMediaPermissionForOrigin(WKSecurityOriginRef, const WKUserMediaPermissionCheckRef&);
+    void setUserMediaPermissionForOrigin(bool, WKStringRef userMediaDocumentOriginString, WKStringRef topLevelDocumentOriginString);
+    void handleUserMediaPermissionRequest(WKFrameRef, WKSecurityOriginRef, WKSecurityOriginRef, WKUserMediaPermissionRequestRef);
+    void handleCheckOfUserMediaPermissionForOrigin(WKFrameRef, WKSecurityOriginRef, WKSecurityOriginRef, const WKUserMediaPermissionCheckRef&);
 
     // Policy delegate.
     void setCustomPolicyDelegate(bool enabled, bool permissive);
@@ -288,9 +293,9 @@ private:
     bool m_isGeolocationPermissionSet;
     bool m_isGeolocationPermissionAllowed;
 
-    WKRetainPtr<WKMutableDictionaryRef> m_userMediaOriginPermissions;
+    HashMap<String, RefPtr<OriginSettings>> m_cahcedUserMediaPermissions;
 
-    typedef Vector<std::pair<WKRetainPtr<WKSecurityOriginRef>, WKRetainPtr<WKUserMediaPermissionRequestRef>>> PermissionRequestList;
+    typedef Vector<std::pair<String, WKRetainPtr<WKUserMediaPermissionRequestRef>>> PermissionRequestList;
     PermissionRequestList m_userMediaPermissionRequests;
 
     bool m_isUserMediaPermissionSet;
index 6ab3892..01ff5da 100644 (file)
@@ -477,10 +477,13 @@ void TestInvocation::didReceiveMessageFromInjectedBundle(WKStringRef messageName
         WKBooleanRef permissionWK = static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(messageBodyDictionary, permissionKeyWK.get()));
         bool permission = WKBooleanGetValue(permissionWK);
 
-        WKRetainPtr<WKStringRef> urlKey(AdoptWK, WKStringCreateWithUTF8CString("url"));
-        WKStringRef urlWK = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, urlKey.get()));
+        WKRetainPtr<WKStringRef> originKey(AdoptWK, WKStringCreateWithUTF8CString("origin"));
+        WKStringRef originWK = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, originKey.get()));
+
+        WKRetainPtr<WKStringRef> parentOriginKey(AdoptWK, WKStringCreateWithUTF8CString("parentOrigin"));
+        WKStringRef parentOriginWK = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, parentOriginKey.get()));
 
-        TestController::singleton().setUserMediaPermissionForOrigin(permission, urlWK);
+        TestController::singleton().setUserMediaPermissionForOrigin(permission, originWK, parentOriginWK);
         return;
     }