<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[193944] trunk</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/193944">193944</a></dd>
<dt>Author</dt> <dd>eric.carlson@apple.com</dd>
<dt>Date</dt> <dd>2015-12-10 20:06:05 -0800 (Thu, 10 Dec 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>[MediaStream] Expose media capture devices persistent permissions to WebCore
https://bugs.webkit.org/show_bug.cgi?id=152087

Source/WebCore:

Reviewed by Chris Dumez.

No new tests, an existing test was updated to test the change.

* CMakeLists.txt: Add UserMediaPermissionCheck.cpp.

* Modules/mediastream/MediaDevicesRequest.cpp:
(WebCore::MediaDevicesRequest::~MediaDevicesRequest): Clear the permission checker client.
(WebCore::MediaDevicesRequest::contextDestroyed): Ditto.
(WebCore::MediaDevicesRequest::start): Create a permission checker and start it running.
(WebCore::MediaDevicesRequest::didCompleteCheck): Start the media source checker.
(WebCore::MediaDevicesRequest::didCompleteRequest): Only include a track's label if the
  page has permission to use a capture device.
* Modules/mediastream/MediaDevicesRequest.h:

* Modules/mediastream/UserMediaClient.h: Include prototypes for permission checker.
(WebCore::UserMediaClient::~UserMediaClient):
        
* Modules/mediastream/MediaStreamTrackSourcesRequest.cpp: Removed, not longer used.
* Modules/mediastream/MediaStreamTrackSourcesRequest.h:

* Modules/mediastream/UserMediaController.h:
(WebCore::UserMediaController::checkUserMediaPermission): New.
(WebCore::UserMediaController::cancelUserMediaPermissionCheck): Ditto.

* Modules/mediastream/UserMediaPermissionCheck.cpp: Added.
(WebCore::UserMediaPermissionCheck::create):
(WebCore::UserMediaPermissionCheck::UserMediaPermissionCheck):
(WebCore::UserMediaPermissionCheck::~UserMediaPermissionCheck):
(WebCore::UserMediaPermissionCheck::securityOrigin):
(WebCore::UserMediaPermissionCheck::contextDestroyed):
(WebCore::UserMediaPermissionCheck::start):
(WebCore::UserMediaPermissionCheck::setDeviceAccessMode):
* Modules/mediastream/UserMediaPermissionCheck.h: Added.
(WebCore::UserMediaPermissionCheckClient::~UserMediaPermissionCheckClient):
(WebCore::UserMediaPermissionCheck::setClient):

* WebCore.xcodeproj/project.pbxproj: Add UserMediaPermissionCheck.cpp|.h

* platform/mock/UserMediaClientMock.h: Removed, it is no longer used.

* testing/Internals.cpp: Remove UserMediaClientMock.h include, it is gone.

Source/WebKit/mac:

Reviewed by Chris Dumez.

Add methods and helpers for WK1 permission checker interface.
* WebCoreSupport/WebUserMediaClient.h:
* WebCoreSupport/WebUserMediaClient.mm:
(userMediaRequestsMap):
(AddRequestToRequestMap):
(RemoveRequestFromRequestMap):
(userMediaCheckMap):
(AddPermissionCheckToMap):
(RemovePermissionCheckFromMap):
(WebUserMediaClient::WebUserMediaClient):
(WebUserMediaClient::requestUserMediaAccess):
(WebUserMediaClient::cancelUserMediaAccessRequest):
(WebUserMediaClient::checkUserMediaPermission):
(WebUserMediaClient::cancelUserMediaPermissionCheck):
(-[WebUserMediaPolicyListener allow]):
(-[WebUserMediaPolicyListener deny]):
(-[WebUserMediaPolicyCheckerListener initWithUserMediaPermissionCheck:]):
(-[WebUserMediaPolicyCheckerListener cancelUserMediaPermissionCheck]):
(-[WebUserMediaPolicyCheckerListener allow]):
(-[WebUserMediaPolicyCheckerListener deny]):
(-[WebUserMediaPolicyCheckerListener denyOnlyThisRequest]):
(-[WebUserMediaPolicyCheckerListener shouldClearCache]):
(AddRequestToMap): Deleted.
(RemoveRequestFromMap): Deleted.
* WebView/WebUIDelegatePrivate.h:

Source/WebKit2:

Reviewed by Chris Dumez.

* CMakeLists.txt: Add UserMediaPermissionCheckProxy.cpp and WKUserMediaPermissionCheck.cpp.

* Shared/API/APIObject.h: Define UserMediaPermissionCheck.

* Shared/API/c/WKBase.h: Add WKUserMediaPermissionCheckRef typedef.

* UIProcess/API/APIUIClient.h:
(API::UIClient::checkUserMediaPermissionForOrigin): New.

* UIProcess/API/C/WKAPICast.h: Add WKUserMediaPermissionCheckRef/UserMediaPermissionCheckProxy mapping.

* UIProcess/API/C/WKPage.cpp:
(WKPageSetPageUIClient): Implement checkUserMediaPermissionForOrigin.

* UIProcess/API/C/WKPageUIClient.h: Add WKCheckUserMediaPermissionCallback typedef and add
  checkUserMediaPermissionForOrigin to WKPageUIClientV6.

* UIProcess/API/C/WKUserMediaPermissionCheck.cpp: Added.
(WKUserMediaPermissionCheckGetTypeID):
(WKUserMediaPermissionCheckSetHasPermission):

* UIProcess/API/C/WKUserMediaPermissionCheck.h: Added.

* UIProcess/UserMediaPermissionCheckProxy.cpp: Added.
(WebKit::UserMediaPermissionCheckProxy::UserMediaPermissionCheckProxy):
(WebKit::UserMediaPermissionCheckProxy::setHasPermission):
(WebKit::UserMediaPermissionCheckProxy::invalidate):
* UIProcess/UserMediaPermissionCheckProxy.h: Added.
(WebKit::UserMediaPermissionCheckProxy::create):
* UIProcess/UserMediaPermissionRequestManagerProxy.cpp:
(WebKit::UserMediaPermissionRequestManagerProxy::invalidateRequests):
(WebKit::UserMediaPermissionRequestManagerProxy::createRequest):
(WebKit::UserMediaPermissionRequestManagerProxy::didReceiveUserMediaPermissionDecision):
(WebKit::UserMediaPermissionRequestManagerProxy::createUserMediaPermissionCheck):
(WebKit::UserMediaPermissionRequestManagerProxy::didCompleteUserMediaPermissionCheck):
* UIProcess/UserMediaPermissionRequestManagerProxy.h:
* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::requestUserMediaPermissionForFrame):
(WebKit::WebPageProxy::checkUserMediaPermissionForFrame):
(WebKit::WebPageProxy::requestNotificationPermission):
* UIProcess/WebPageProxy.h:
* UIProcess/WebPageProxy.messages.in:

* WebKit2.xcodeproj/project.pbxproj: Add UserMediaPermissionCheckProxy.*, and WKUserMediaPermissionCheck.*.

* WebProcess/MediaStream/UserMediaPermissionRequestManager.cpp:
(WebKit::UserMediaPermissionRequestManager::startUserMediaRequest): Renamed from startRequest.
(WebKit::UserMediaPermissionRequestManager::cancelUserMediaRequest): Renamed from cancelRequest.
(WebKit::UserMediaPermissionRequestManager::didReceiveUserMediaPermissionDecision): m_requestToIDMap -&gt;
  m_userMediaRequestToIDMap.remove.
(WebKit::UserMediaPermissionRequestManager::startUserMediaPermissionCheck): New, start the request.
(WebKit::UserMediaPermissionRequestManager::cancelUserMediaPermissionCheck): New, cancel
  the request.
(WebKit::UserMediaPermissionRequestManager::didCompleteUserMediaPermissionCheck): New, 
  all the request completion method.
(WebKit::UserMediaPermissionRequestManager::startRequest): Deleted.
(WebKit::UserMediaPermissionRequestManager::cancelRequest): Deleted.
* WebProcess/MediaStream/UserMediaPermissionRequestManager.h:

* WebProcess/WebCoreSupport/WebUserMediaClient.cpp:
(WebKit::WebUserMediaClient::requestUserMediaAccess): startRequest -&gt; startUserMediaRequest.
(WebKit::WebUserMediaClient::cancelUserMediaAccessRequest): cancelRequest -&gt; cancelUserMediaRequest.
(WebKit::WebUserMediaClient::checkUserMediaPermission): New.
(WebKit::WebUserMediaClient::cancelUserMediaPermissionCheck): New.
* WebProcess/WebCoreSupport/WebUserMediaClient.h:

* WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::didCompleteUserMediaPermissionCheck): New.
* WebProcess/WebPage/WebPage.h:
* WebProcess/WebPage/WebPage.messages.in: Add DidCompleteUserMediaPermissionCheck.

Tools:

Add support for the new user media permission checker page UI client method.

Reviewed by Chris Dumez.

* WebKitTestRunner/TestController.cpp:
(WTR::decidePolicyForUserMediaPermissionRequest):
(WTR::checkUserMediaPermissionForOrigin):
(WTR::TestController::createOtherPage): Add checkUserMediaPermissionForOrigin.
(WTR::TestController::createWebViewWithOptions): Ditto.
(WTR::TestController::resetStateToConsistentValues): Clear m_userMediaOriginPermissions.
(WTR::originUserVisibleName): New, create a string for the origin.
(WTR::TestController::handleCheckOfUserMediaPermissionForOrigin): Set the WKUserMediaPermissionCheckRef
  according to the state of the origin permission map.
(WTR::TestController::handleUserMediaPermissionRequest): Remember both the origin and the
  request so we can update the origin permission map in decidePolicyForUserMediaPermissionRequestIfPossible.
(WTR::TestController::decidePolicyForUserMediaPermissionRequestIfPossible): Update the
  origin permission map.
* WebKitTestRunner/TestController.h:

LayoutTests:

Reviewed by Chris Dumez.

* fast/mediastream/MediaDevices-enumerateDevices-expected.txt:
* fast/mediastream/MediaDevices-enumerateDevices.html:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsfastmediastreamMediaDevicesenumerateDevicesexpectedtxt">trunk/LayoutTests/fast/mediastream/MediaDevices-enumerateDevices-expected.txt</a></li>
<li><a href="#trunkLayoutTestsfastmediastreamMediaDevicesenumerateDeviceshtml">trunk/LayoutTests/fast/mediastream/MediaDevices-enumerateDevices.html</a></li>
<li><a href="#trunkSourceWebCoreCMakeListstxt">trunk/Source/WebCore/CMakeLists.txt</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreModulesmediastreamMediaDevicesRequestcpp">trunk/Source/WebCore/Modules/mediastream/MediaDevicesRequest.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesmediastreamMediaDevicesRequesth">trunk/Source/WebCore/Modules/mediastream/MediaDevicesRequest.h</a></li>
<li><a href="#trunkSourceWebCoreModulesmediastreamUserMediaClienth">trunk/Source/WebCore/Modules/mediastream/UserMediaClient.h</a></li>
<li><a href="#trunkSourceWebCoreModulesmediastreamUserMediaControllerh">trunk/Source/WebCore/Modules/mediastream/UserMediaController.h</a></li>
<li><a href="#trunkSourceWebCoreWebCorexcodeprojprojectpbxproj">trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceWebCoretestingInternalscpp">trunk/Source/WebCore/testing/Internals.cpp</a></li>
<li><a href="#trunkSourceWebKitmacChangeLog">trunk/Source/WebKit/mac/ChangeLog</a></li>
<li><a href="#trunkSourceWebKitmacWebCoreSupportWebUserMediaClienth">trunk/Source/WebKit/mac/WebCoreSupport/WebUserMediaClient.h</a></li>
<li><a href="#trunkSourceWebKitmacWebCoreSupportWebUserMediaClientmm">trunk/Source/WebKit/mac/WebCoreSupport/WebUserMediaClient.mm</a></li>
<li><a href="#trunkSourceWebKitmacWebViewWebUIDelegatePrivateh">trunk/Source/WebKit/mac/WebView/WebUIDelegatePrivate.h</a></li>
<li><a href="#trunkSourceWebKit2CMakeListstxt">trunk/Source/WebKit2/CMakeLists.txt</a></li>
<li><a href="#trunkSourceWebKit2ChangeLog">trunk/Source/WebKit2/ChangeLog</a></li>
<li><a href="#trunkSourceWebKit2SharedAPIAPIObjecth">trunk/Source/WebKit2/Shared/API/APIObject.h</a></li>
<li><a href="#trunkSourceWebKit2SharedAPIcWKBaseh">trunk/Source/WebKit2/Shared/API/c/WKBase.h</a></li>
<li><a href="#trunkSourceWebKit2UIProcessAPIAPIUIClienth">trunk/Source/WebKit2/UIProcess/API/APIUIClient.h</a></li>
<li><a href="#trunkSourceWebKit2UIProcessAPICWKAPICasth">trunk/Source/WebKit2/UIProcess/API/C/WKAPICast.h</a></li>
<li><a href="#trunkSourceWebKit2UIProcessAPICWKPagecpp">trunk/Source/WebKit2/UIProcess/API/C/WKPage.cpp</a></li>
<li><a href="#trunkSourceWebKit2UIProcessAPICWKPageUIClienth">trunk/Source/WebKit2/UIProcess/API/C/WKPageUIClient.h</a></li>
<li><a href="#trunkSourceWebKit2UIProcessUserMediaPermissionRequestManagerProxycpp">trunk/Source/WebKit2/UIProcess/UserMediaPermissionRequestManagerProxy.cpp</a></li>
<li><a href="#trunkSourceWebKit2UIProcessUserMediaPermissionRequestManagerProxyh">trunk/Source/WebKit2/UIProcess/UserMediaPermissionRequestManagerProxy.h</a></li>
<li><a href="#trunkSourceWebKit2UIProcessUserMediaPermissionRequestProxyh">trunk/Source/WebKit2/UIProcess/UserMediaPermissionRequestProxy.h</a></li>
<li><a href="#trunkSourceWebKit2UIProcessWebPageProxycpp">trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp</a></li>
<li><a href="#trunkSourceWebKit2UIProcessWebPageProxyh">trunk/Source/WebKit2/UIProcess/WebPageProxy.h</a></li>
<li><a href="#trunkSourceWebKit2UIProcessWebPageProxymessagesin">trunk/Source/WebKit2/UIProcess/WebPageProxy.messages.in</a></li>
<li><a href="#trunkSourceWebKit2WebKit2xcodeprojprojectpbxproj">trunk/Source/WebKit2/WebKit2.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceWebKit2WebProcessMediaStreamUserMediaPermissionRequestManagercpp">trunk/Source/WebKit2/WebProcess/MediaStream/UserMediaPermissionRequestManager.cpp</a></li>
<li><a href="#trunkSourceWebKit2WebProcessMediaStreamUserMediaPermissionRequestManagerh">trunk/Source/WebKit2/WebProcess/MediaStream/UserMediaPermissionRequestManager.h</a></li>
<li><a href="#trunkSourceWebKit2WebProcessWebCoreSupportWebUserMediaClientcpp">trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebUserMediaClient.cpp</a></li>
<li><a href="#trunkSourceWebKit2WebProcessWebCoreSupportWebUserMediaClienth">trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebUserMediaClient.h</a></li>
<li><a href="#trunkSourceWebKit2WebProcessWebPageWebPagecpp">trunk/Source/WebKit2/WebProcess/WebPage/WebPage.cpp</a></li>
<li><a href="#trunkSourceWebKit2WebProcessWebPageWebPageh">trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h</a></li>
<li><a href="#trunkSourceWebKit2WebProcessWebPageWebPagemessagesin">trunk/Source/WebKit2/WebProcess/WebPage/WebPage.messages.in</a></li>
<li><a href="#trunkToolsChangeLog">trunk/Tools/ChangeLog</a></li>
<li><a href="#trunkToolsWebKitTestRunnerTestControllercpp">trunk/Tools/WebKitTestRunner/TestController.cpp</a></li>
<li><a href="#trunkToolsWebKitTestRunnerTestControllerh">trunk/Tools/WebKitTestRunner/TestController.h</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreModulesmediastreamUserMediaPermissionCheckcpp">trunk/Source/WebCore/Modules/mediastream/UserMediaPermissionCheck.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesmediastreamUserMediaPermissionCheckh">trunk/Source/WebCore/Modules/mediastream/UserMediaPermissionCheck.h</a></li>
<li><a href="#trunkSourceWebKit2UIProcessAPICWKUserMediaPermissionCheckcpp">trunk/Source/WebKit2/UIProcess/API/C/WKUserMediaPermissionCheck.cpp</a></li>
<li><a href="#trunkSourceWebKit2UIProcessAPICWKUserMediaPermissionCheckh">trunk/Source/WebKit2/UIProcess/API/C/WKUserMediaPermissionCheck.h</a></li>
<li><a href="#trunkSourceWebKit2UIProcessUserMediaPermissionCheckProxycpp">trunk/Source/WebKit2/UIProcess/UserMediaPermissionCheckProxy.cpp</a></li>
<li><a href="#trunkSourceWebKit2UIProcessUserMediaPermissionCheckProxyh">trunk/Source/WebKit2/UIProcess/UserMediaPermissionCheckProxy.h</a></li>
</ul>

<h3>Removed Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreModulesmediastreamMediaStreamTrackSourcesRequestcpp">trunk/Source/WebCore/Modules/mediastream/MediaStreamTrackSourcesRequest.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesmediastreamMediaStreamTrackSourcesRequesth">trunk/Source/WebCore/Modules/mediastream/MediaStreamTrackSourcesRequest.h</a></li>
<li><a href="#trunkSourceWebCoreplatformmockUserMediaClientMockh">trunk/Source/WebCore/platform/mock/UserMediaClientMock.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (193943 => 193944)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2015-12-11 04:03:28 UTC (rev 193943)
+++ trunk/LayoutTests/ChangeLog        2015-12-11 04:06:05 UTC (rev 193944)
</span><span class="lines">@@ -1,3 +1,13 @@
</span><ins>+2015-12-10  Eric Carlson  &lt;eric.carlson@apple.com&gt;
+
+        [MediaStream] Expose media capture devices persistent permissions to WebCore
+        https://bugs.webkit.org/show_bug.cgi?id=152087
+
+        Reviewed by Chris Dumez.
+
+        * fast/mediastream/MediaDevices-enumerateDevices-expected.txt:
+        * fast/mediastream/MediaDevices-enumerateDevices.html:
+
</ins><span class="cx"> 2015-12-10  Daniel Bates  &lt;dabates@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [CSP] eval() is not blocked for stringified literals
</span></span></pre></div>
<a id="trunkLayoutTestsfastmediastreamMediaDevicesenumerateDevicesexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/fast/mediastream/MediaDevices-enumerateDevices-expected.txt (193943 => 193944)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/mediastream/MediaDevices-enumerateDevices-expected.txt        2015-12-11 04:03:28 UTC (rev 193943)
+++ trunk/LayoutTests/fast/mediastream/MediaDevices-enumerateDevices-expected.txt        2015-12-11 04:06:05 UTC (rev 193944)
</span><span class="lines">@@ -6,18 +6,40 @@
</span><span class="cx"> PASS navigator.mediaDevices is an instance of Object
</span><span class="cx"> PASS navigator.mediaDevices.enumerateDevices is an instance of Function
</span><span class="cx"> 
</span><ins>+
+*** Calling mediaDevices.enumerateDevices when persistent access HAS NOT been granted
+
</ins><span class="cx"> PASS captureDevices.length is non-zero.
</span><span class="cx"> 
</span><span class="cx"> PASS captureDevice.kind is non-null.
</span><span class="cx"> PASS captureDevice.deviceId is non-null.
</span><span class="cx"> PASS captureDevice.label is non-null.
</span><ins>+PASS captureDevice.label is &quot;&quot;
</ins><span class="cx"> PASS captureDevice.groupId is non-null.
</span><span class="cx"> 
</span><span class="cx"> PASS captureDevice.kind is non-null.
</span><span class="cx"> PASS captureDevice.deviceId is non-null.
</span><span class="cx"> PASS captureDevice.label is non-null.
</span><ins>+PASS captureDevice.label is &quot;&quot;
</ins><span class="cx"> PASS captureDevice.groupId is non-null.
</span><span class="cx"> 
</span><ins>+
+*** Calling mediaDevices.enumerateDevices when persistent access HAS been granted
+
+PASS captureDevices.length is non-zero.
+
+PASS captureDevice.kind is non-null.
+PASS captureDevice.deviceId is non-null.
+PASS captureDevice.label is non-null.
+PASS captureDevice.label is not &quot;&quot;
+PASS captureDevice.groupId is non-null.
+
+PASS captureDevice.kind is non-null.
+PASS captureDevice.deviceId is non-null.
+PASS captureDevice.label is non-null.
+PASS captureDevice.label is not &quot;&quot;
+PASS captureDevice.groupId is non-null.
+
</ins><span class="cx"> PASS successfullyParsed is true
</span><span class="cx"> 
</span><span class="cx"> TEST COMPLETE
</span></span></pre></div>
<a id="trunkLayoutTestsfastmediastreamMediaDevicesenumerateDeviceshtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/fast/mediastream/MediaDevices-enumerateDevices.html (193943 => 193944)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/mediastream/MediaDevices-enumerateDevices.html        2015-12-11 04:03:28 UTC (rev 193943)
+++ trunk/LayoutTests/fast/mediastream/MediaDevices-enumerateDevices.html        2015-12-11 04:06:05 UTC (rev 193944)
</span><span class="lines">@@ -9,6 +9,7 @@
</span><span class="cx">         &lt;script&gt;
</span><span class="cx">             var captureDevices;
</span><span class="cx">             var captureDevice;
</span><ins>+            var havePermission;
</ins><span class="cx"> 
</span><span class="cx">             description(&quot;Tests MediaDevices.enumerateDevices()&quot;);
</span><span class="cx">             window.jsTestIsAsync = true;
</span><span class="lines">@@ -17,25 +18,54 @@
</span><span class="cx">             shouldBeType(&quot;navigator.mediaDevices.enumerateDevices&quot;, &quot;Function&quot;);
</span><span class="cx">             debug(&quot;&quot;);
</span><span class="cx"> 
</span><del>-            navigator.mediaDevices.enumerateDevices()
-                .then(function(devices) {
-                    captureDevices = devices;
-                    shouldBeNonZero(&quot;captureDevices.length&quot;);
-                    debug(&quot;&quot;);
-                    devices.forEach(function(device) {
-                        captureDevice = device;
-                        shouldBeNonNull(&quot;captureDevice.kind&quot;);
-                        shouldBeNonNull(&quot;captureDevice.deviceId&quot;);
-                        shouldBeNonNull(&quot;captureDevice.label&quot;);
-                        shouldBeNonNull(&quot;captureDevice.groupId&quot;);
</del><ins>+            function enumerate(next)
+            {
+                debug(`&lt;br&gt;*** Calling mediaDevices.enumerateDevices when persistent access HAS ${havePermission ? &quot;&quot; : &quot;NOT &quot;}been granted&lt;br&gt;`);
+                navigator.mediaDevices.enumerateDevices()
+                    .then(function(devices) {
+                        captureDevices = devices;
+                        shouldBeNonZero(&quot;captureDevices.length&quot;);
</ins><span class="cx">                         debug(&quot;&quot;);
</span><ins>+                        devices.forEach(function(device) {
+                            captureDevice = device;
+                            shouldBeNonNull(&quot;captureDevice.kind&quot;);
+                            shouldBeNonNull(&quot;captureDevice.deviceId&quot;);
+                            shouldBeNonNull(&quot;captureDevice.label&quot;);
+                            if (havePermission)
+                                shouldNotBeEqualToString(&quot;captureDevice.label&quot;, &quot;&quot;);
+                            else
+                                shouldBeEmptyString(&quot;captureDevice.label&quot;);
+                            shouldBeNonNull(&quot;captureDevice.groupId&quot;);
+                            debug(&quot;&quot;);
+                        });
+                        if (next)
+                            next();
+                        else
+                            finishJSTest();
+                    })
+                    .catch(function(err) {
+                        testFailed(err.name + &quot;: &quot; + err.message);
</ins><span class="cx">                     });
</span><ins>+            }
+            
+            function grantPermission()
+            {
+                if (window.testRunner) {
+                    testRunner.setUserMediaPermission(true);
+                    navigator.mediaDevices
+                        .getUserMedia({audio:{}, video:{}})
+                        .then(function(stream) {
+                            havePermission = true;
+                            enumerate(null);                        
+                        })
+                        .catch(function(err) {
+                            testFailed(`mediaDevices.getUserMedia() failed with ${err.name}: ${err.message}`);
+                        });
+                }
+            }
</ins><span class="cx"> 
</span><del>-                    finishJSTest();
-                })
-                .catch(function(err) {
-                    testFailed(err.name + &quot;: &quot; + err.message);
-                });
</del><ins>+            havePermission = false;
+            enumerate(grantPermission);
</ins><span class="cx"> 
</span><span class="cx">             window.successfullyParsed = true;
</span><span class="cx">         &lt;/script&gt;
</span></span></pre></div>
<a id="trunkSourceWebCoreCMakeListstxt"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/CMakeLists.txt (193943 => 193944)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/CMakeLists.txt        2015-12-11 04:03:28 UTC (rev 193943)
+++ trunk/Source/WebCore/CMakeLists.txt        2015-12-11 04:06:05 UTC (rev 193944)
</span><span class="lines">@@ -952,7 +952,6 @@
</span><span class="cx">     Modules/mediastream/MediaStreamRegistry.cpp
</span><span class="cx">     Modules/mediastream/MediaStreamTrack.cpp
</span><span class="cx">     Modules/mediastream/MediaStreamTrackEvent.cpp
</span><del>-    Modules/mediastream/MediaStreamTrackSourcesRequest.cpp
</del><span class="cx">     Modules/mediastream/MediaTrackConstraint.cpp
</span><span class="cx">     Modules/mediastream/MediaTrackConstraintSet.cpp
</span><span class="cx">     Modules/mediastream/MediaTrackConstraints.cpp
</span><span class="lines">@@ -975,6 +974,7 @@
</span><span class="cx">     Modules/mediastream/RTCTrackEvent.cpp
</span><span class="cx">     Modules/mediastream/SourceInfo.cpp
</span><span class="cx">     Modules/mediastream/UserMediaController.cpp
</span><ins>+    Modules/mediastream/UserMediaPermissionCheck.cpp
</ins><span class="cx">     Modules/mediastream/UserMediaRequest.cpp
</span><span class="cx"> 
</span><span class="cx">     Modules/navigatorcontentutils/NavigatorContentUtils.cpp
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (193943 => 193944)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2015-12-11 04:03:28 UTC (rev 193943)
+++ trunk/Source/WebCore/ChangeLog        2015-12-11 04:06:05 UTC (rev 193944)
</span><span class="lines">@@ -1,3 +1,51 @@
</span><ins>+2015-12-10  Eric Carlson  &lt;eric.carlson@apple.com&gt;
+
+        [MediaStream] Expose media capture devices persistent permissions to WebCore
+        https://bugs.webkit.org/show_bug.cgi?id=152087
+
+        Reviewed by Chris Dumez.
+
+        No new tests, an existing test was updated to test the change.
+
+        * CMakeLists.txt: Add UserMediaPermissionCheck.cpp.
+
+        * Modules/mediastream/MediaDevicesRequest.cpp:
+        (WebCore::MediaDevicesRequest::~MediaDevicesRequest): Clear the permission checker client.
+        (WebCore::MediaDevicesRequest::contextDestroyed): Ditto.
+        (WebCore::MediaDevicesRequest::start): Create a permission checker and start it running.
+        (WebCore::MediaDevicesRequest::didCompleteCheck): Start the media source checker.
+        (WebCore::MediaDevicesRequest::didCompleteRequest): Only include a track's label if the
+          page has permission to use a capture device.
+        * Modules/mediastream/MediaDevicesRequest.h:
+
+        * Modules/mediastream/UserMediaClient.h: Include prototypes for permission checker.
+        (WebCore::UserMediaClient::~UserMediaClient):
+        
+        * Modules/mediastream/MediaStreamTrackSourcesRequest.cpp: Removed, not longer used.
+        * Modules/mediastream/MediaStreamTrackSourcesRequest.h:
+
+        * Modules/mediastream/UserMediaController.h:
+        (WebCore::UserMediaController::checkUserMediaPermission): New.
+        (WebCore::UserMediaController::cancelUserMediaPermissionCheck): Ditto.
+
+        * Modules/mediastream/UserMediaPermissionCheck.cpp: Added.
+        (WebCore::UserMediaPermissionCheck::create):
+        (WebCore::UserMediaPermissionCheck::UserMediaPermissionCheck):
+        (WebCore::UserMediaPermissionCheck::~UserMediaPermissionCheck):
+        (WebCore::UserMediaPermissionCheck::securityOrigin):
+        (WebCore::UserMediaPermissionCheck::contextDestroyed):
+        (WebCore::UserMediaPermissionCheck::start):
+        (WebCore::UserMediaPermissionCheck::setDeviceAccessMode):
+        * Modules/mediastream/UserMediaPermissionCheck.h: Added.
+        (WebCore::UserMediaPermissionCheckClient::~UserMediaPermissionCheckClient):
+        (WebCore::UserMediaPermissionCheck::setClient):
+
+        * WebCore.xcodeproj/project.pbxproj: Add UserMediaPermissionCheck.cpp|.h
+
+        * platform/mock/UserMediaClientMock.h: Removed, it is no longer used.
+
+        * testing/Internals.cpp: Remove UserMediaClientMock.h include, it is gone.
+
</ins><span class="cx"> 2015-12-10  Myles C. Maxfield  &lt;mmaxfield@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Build fix
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesmediastreamMediaDevicesRequestcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/mediastream/MediaDevicesRequest.cpp (193943 => 193944)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/mediastream/MediaDevicesRequest.cpp        2015-12-11 04:03:28 UTC (rev 193943)
+++ trunk/Source/WebCore/Modules/mediastream/MediaDevicesRequest.cpp        2015-12-11 04:06:05 UTC (rev 193944)
</span><span class="lines">@@ -52,6 +52,8 @@
</span><span class="cx"> 
</span><span class="cx"> MediaDevicesRequest::~MediaDevicesRequest()
</span><span class="cx"> {
</span><ins>+    if (m_permissionCheck)
+        m_permissionCheck-&gt;setClient(nullptr);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> SecurityOrigin* MediaDevicesRequest::securityOrigin() const
</span><span class="lines">@@ -65,28 +67,46 @@
</span><span class="cx"> void MediaDevicesRequest::contextDestroyed()
</span><span class="cx"> {
</span><span class="cx">     ContextDestructionObserver::contextDestroyed();
</span><ins>+    if (m_permissionCheck) {
+        m_permissionCheck-&gt;setClient(nullptr);
+        m_permissionCheck = nullptr;
+    }
</ins><span class="cx">     m_protector = nullptr;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void MediaDevicesRequest::start()
</span><span class="cx"> {
</span><span class="cx">     m_protector = this;
</span><del>-    RealtimeMediaSourceCenter::singleton().getMediaStreamTrackSources(this);
</del><ins>+    m_permissionCheck = UserMediaPermissionCheck::create(*downcast&lt;Document&gt;(scriptExecutionContext()), *this);
+    m_permissionCheck-&gt;start();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void MediaDevicesRequest::didCompleteCheck(bool canAccess)
+{
+    m_permissionCheck-&gt;setClient(nullptr);
+    m_permissionCheck = nullptr;
+
+    m_hasUserMediaPermission = canAccess;
+
+    callOnMainThread([this] {
+        RealtimeMediaSourceCenter::singleton().getMediaStreamTrackSources(this);
+    });
+}
+
</ins><span class="cx"> void MediaDevicesRequest::didCompleteRequest(const TrackSourceInfoVector&amp; capturedDevices)
</span><span class="cx"> {
</span><del>-    if (!m_scriptExecutionContext)
</del><ins>+    if (!m_scriptExecutionContext) {
+        m_protector = nullptr;
</ins><span class="cx">         return;
</span><ins>+    }
</ins><span class="cx"> 
</span><span class="cx">     Vector&lt;RefPtr&lt;MediaDeviceInfo&gt;&gt; deviceInfo;
</span><span class="cx">     for (auto device : capturedDevices) {
</span><span class="cx">         TrackSourceInfo* trackInfo = device.get();
</span><span class="cx">         String deviceType = trackInfo-&gt;kind() == TrackSourceInfo::SourceKind::Audio ? MediaDeviceInfo::audioInputType() : MediaDeviceInfo::videoInputType();
</span><span class="cx"> 
</span><del>-        // FIXME: label is supposed to be empty unless a device is attached to an active MediaStreamTrack in the current browsing context, or
-        // persistent permission to access these local devices has been granted to the page's origin.
-        deviceInfo.append(MediaDeviceInfo::create(m_scriptExecutionContext, trackInfo-&gt;label(), trackInfo-&gt;id(), trackInfo-&gt;groupId(), deviceType));
</del><ins>+        AtomicString label = m_hasUserMediaPermission ? trackInfo-&gt;label() : emptyAtom;
+        deviceInfo.append(MediaDeviceInfo::create(m_scriptExecutionContext, label, trackInfo-&gt;id(), trackInfo-&gt;groupId(), deviceType));
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     RefPtr&lt;MediaDevicesRequest&gt; protectedThis(this);
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesmediastreamMediaDevicesRequesth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/mediastream/MediaDevicesRequest.h (193943 => 193944)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/mediastream/MediaDevicesRequest.h        2015-12-11 04:03:28 UTC (rev 193943)
+++ trunk/Source/WebCore/Modules/mediastream/MediaDevicesRequest.h        2015-12-11 04:06:05 UTC (rev 193944)
</span><span class="lines">@@ -33,6 +33,7 @@
</span><span class="cx"> #include &quot;MediaDevices.h&quot;
</span><span class="cx"> #include &quot;MediaStreamCreationClient.h&quot;
</span><span class="cx"> #include &quot;MediaStreamTrackSourcesRequestClient.h&quot;
</span><ins>+#include &quot;UserMediaPermissionCheck.h&quot;
</ins><span class="cx"> #include &lt;wtf/PassRefPtr.h&gt;
</span><span class="cx"> #include &lt;wtf/RefCounted.h&gt;
</span><span class="cx"> #include &lt;wtf/text/WTFString.h&gt;
</span><span class="lines">@@ -45,7 +46,7 @@
</span><span class="cx"> 
</span><span class="cx"> typedef int ExceptionCode;
</span><span class="cx"> 
</span><del>-class MediaDevicesRequest : public MediaStreamTrackSourcesRequestClient, public ContextDestructionObserver {
</del><ins>+class MediaDevicesRequest : public MediaStreamTrackSourcesRequestClient, public UserMediaPermissionCheckClient, public ContextDestructionObserver {
</ins><span class="cx"> public:
</span><span class="cx">     static RefPtr&lt;MediaDevicesRequest&gt; create(Document*, MediaDevices::EnumerateDevicesPromise&amp;&amp;, ExceptionCode&amp;);
</span><span class="cx"> 
</span><span class="lines">@@ -63,10 +64,16 @@
</span><span class="cx">     void didCompleteRequest(const TrackSourceInfoVector&amp;) final;
</span><span class="cx"> 
</span><span class="cx">     // ContextDestructionObserver
</span><del>-    virtual void contextDestroyed() override final;
</del><ins>+    void contextDestroyed() override final;
</ins><span class="cx"> 
</span><ins>+    // UserMediaPermissionCheckClient
+    void didCompleteCheck(bool) override final;
+
</ins><span class="cx">     MediaDevices::EnumerateDevicesPromise m_promise;
</span><span class="cx">     RefPtr&lt;MediaDevicesRequest&gt; m_protector;
</span><ins>+    RefPtr&lt;UserMediaPermissionCheck&gt; m_permissionCheck;
+
+    bool m_hasUserMediaPermission { false };
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesmediastreamMediaStreamTrackSourcesRequestcpp"></a>
<div class="delfile"><h4>Deleted: trunk/Source/WebCore/Modules/mediastream/MediaStreamTrackSourcesRequest.cpp (193943 => 193944)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/mediastream/MediaStreamTrackSourcesRequest.cpp        2015-12-11 04:03:28 UTC (rev 193943)
+++ trunk/Source/WebCore/Modules/mediastream/MediaStreamTrackSourcesRequest.cpp        2015-12-11 04:06:05 UTC (rev 193944)
</span><span class="lines">@@ -1,70 +0,0 @@
</span><del>-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- * Copyright (C) 2013 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 GOOGLE INC. ``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 GOOGLE INC. OR
- * 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 &quot;config.h&quot;
-#include &quot;MediaStreamTrackSourcesRequest.h&quot;
-
-#if ENABLE(MEDIA_STREAM)
-
-#include &quot;MediaStreamTrackSourcesCallback.h&quot;
-#include &quot;ScriptExecutionContext.h&quot;
-#include &quot;SecurityOrigin.h&quot;
-#include &quot;SourceInfo.h&quot;
-#include &lt;wtf/MainThread.h&gt;
-
-namespace WebCore {
-
-Ref&lt;MediaStreamTrackSourcesRequest&gt; MediaStreamTrackSourcesRequest::create(ScriptExecutionContext* context, PassRefPtr&lt;MediaStreamTrackSourcesCallback&gt; callback)
-{
-    return adoptRef(*new MediaStreamTrackSourcesRequest(context, callback));
-}
-
-MediaStreamTrackSourcesRequest::MediaStreamTrackSourcesRequest(ScriptExecutionContext* context, PassRefPtr&lt;MediaStreamTrackSourcesCallback&gt; callback)
-    : m_callback(callback)
-{
-    m_origin = context-&gt;securityOrigin()-&gt;toString();
-}
-
-void MediaStreamTrackSourcesRequest::didCompleteRequest(const TrackSourceInfoVector&amp; requestSourceInfos)
-{
-    ASSERT(m_callback);
-
-    for (auto&amp; info : requestSourceInfos)
-        m_sourceInfos.append(SourceInfo::create(info));
-
-    RefPtr&lt;MediaStreamTrackSourcesRequest&gt; protectedThis(this);
-    callOnMainThread([protectedThis] {
-        RefPtr&lt;MediaStreamTrackSourcesCallback&gt;&amp; callback = protectedThis-&gt;m_callback;
-        ASSERT(callback);
-
-        callback-&gt;handleEvent(protectedThis-&gt;m_sourceInfos);
-        callback = nullptr;
-    });
-}
-
-} // namespace WebCore
-
-#endif
</del></span></pre></div>
<a id="trunkSourceWebCoreModulesmediastreamMediaStreamTrackSourcesRequesth"></a>
<div class="delfile"><h4>Deleted: trunk/Source/WebCore/Modules/mediastream/MediaStreamTrackSourcesRequest.h (193943 => 193944)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/mediastream/MediaStreamTrackSourcesRequest.h        2015-12-11 04:03:28 UTC (rev 193943)
+++ trunk/Source/WebCore/Modules/mediastream/MediaStreamTrackSourcesRequest.h        2015-12-11 04:06:05 UTC (rev 193944)
</span><span class="lines">@@ -1,63 +0,0 @@
</span><del>-/*
- * Copyright (C) 2013 Google 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 GOOGLE INC. ``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 GOOGLE INC. OR
- * 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 MediaStreamTrackSourcesRequest_h
-#define MediaStreamTrackSourcesRequest_h
-
-#if ENABLE(MEDIA_STREAM)
-
-#include &quot;MediaStreamTrackSourcesRequestClient.h&quot;
-#include &quot;SourceInfo.h&quot;
-#include &quot;Timer.h&quot;
-#include &lt;wtf/RefPtr.h&gt;
-#include &lt;wtf/text/WTFString.h&gt;
-
-namespace WebCore {
-
-class MediaStreamTrackSourcesCallback;
-class ScriptExecutionContext;
-
-class MediaStreamTrackSourcesRequest : public MediaStreamTrackSourcesRequestClient {
-public:
-    static Ref&lt;MediaStreamTrackSourcesRequest&gt; create(ScriptExecutionContext*, PassRefPtr&lt;MediaStreamTrackSourcesCallback&gt;);
-    virtual ~MediaStreamTrackSourcesRequest() { }
-
-private:
-    MediaStreamTrackSourcesRequest(ScriptExecutionContext*, PassRefPtr&lt;MediaStreamTrackSourcesCallback&gt;);
-
-    // MediaStreamTrackSourcesRequestClient
-    virtual const String&amp; requestOrigin() const override { return m_origin; }
-    virtual void didCompleteRequest(const TrackSourceInfoVector&amp;) override;
-
-    String m_origin;
-    RefPtr&lt;MediaStreamTrackSourcesCallback&gt; m_callback;
-    Vector&lt;RefPtr&lt;SourceInfo&gt;&gt; m_sourceInfos;
-};
-
-} // namespace WebCore
-
-#endif // MediaStreamTrackSourcesRequest_h
-
-#endif
</del></span></pre></div>
<a id="trunkSourceWebCoreModulesmediastreamUserMediaClienth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/mediastream/UserMediaClient.h (193943 => 193944)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/mediastream/UserMediaClient.h        2015-12-11 04:03:28 UTC (rev 193943)
+++ trunk/Source/WebCore/Modules/mediastream/UserMediaClient.h        2015-12-11 04:06:05 UTC (rev 193944)
</span><span class="lines">@@ -38,15 +38,19 @@
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><span class="cx"> class Page;
</span><ins>+class UserMediaPermissionCheck;
</ins><span class="cx"> class UserMediaRequest;
</span><span class="cx"> 
</span><span class="cx"> class UserMediaClient {
</span><span class="cx"> public:
</span><span class="cx">     virtual void pageDestroyed() = 0;
</span><span class="cx"> 
</span><del>-    virtual void requestUserMediaAccess(Ref&lt;UserMediaRequest&gt;&amp;&amp;) = 0;
</del><ins>+    virtual void requestUserMediaAccess(UserMediaRequest&amp;) = 0;
</ins><span class="cx">     virtual void cancelUserMediaAccessRequest(UserMediaRequest&amp;) = 0;
</span><span class="cx"> 
</span><ins>+    virtual void checkUserMediaPermission(UserMediaPermissionCheck&amp;) = 0;
+    virtual void cancelUserMediaPermissionCheck(UserMediaPermissionCheck&amp;) = 0;
+
</ins><span class="cx"> protected:
</span><span class="cx">     virtual ~UserMediaClient() { }
</span><span class="cx"> };
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesmediastreamUserMediaControllerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/mediastream/UserMediaController.h (193943 => 193944)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/mediastream/UserMediaController.h        2015-12-11 04:03:28 UTC (rev 193943)
+++ trunk/Source/WebCore/Modules/mediastream/UserMediaController.h        2015-12-11 04:06:05 UTC (rev 193944)
</span><span class="lines">@@ -29,6 +29,7 @@
</span><span class="cx"> 
</span><span class="cx"> #include &quot;Page.h&quot;
</span><span class="cx"> #include &quot;UserMediaClient.h&quot;
</span><ins>+#include &quot;UserMediaPermissionCheck.h&quot;
</ins><span class="cx"> #include &quot;UserMediaRequest.h&quot;
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="lines">@@ -40,9 +41,12 @@
</span><span class="cx"> 
</span><span class="cx">     UserMediaClient* client() const { return m_client; }
</span><span class="cx"> 
</span><del>-    void requestUserMediaAccess(Ref&lt;UserMediaRequest&gt;&amp;&amp;);
</del><ins>+    void requestUserMediaAccess(UserMediaRequest&amp;);
</ins><span class="cx">     void cancelUserMediaAccessRequest(UserMediaRequest&amp;);
</span><span class="cx"> 
</span><ins>+    void checkUserMediaPermission(UserMediaPermissionCheck&amp;);
+    void cancelUserMediaPermissionCheck(UserMediaPermissionCheck&amp;);
+
</ins><span class="cx">     WEBCORE_EXPORT static const char* supplementName();
</span><span class="cx">     static UserMediaController* from(Page* page) { return static_cast&lt;UserMediaController*&gt;(Supplement&lt;Page&gt;::from(page, supplementName())); }
</span><span class="cx"> 
</span><span class="lines">@@ -50,9 +54,9 @@
</span><span class="cx">     UserMediaClient* m_client;
</span><span class="cx"> };
</span><span class="cx"> 
</span><del>-inline void UserMediaController::requestUserMediaAccess(Ref&lt;UserMediaRequest&gt;&amp;&amp; request)
</del><ins>+inline void UserMediaController::requestUserMediaAccess(UserMediaRequest&amp; request)
</ins><span class="cx"> {
</span><del>-    m_client-&gt;requestUserMediaAccess(WTF::move(request));
</del><ins>+    m_client-&gt;requestUserMediaAccess(request);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> inline void UserMediaController::cancelUserMediaAccessRequest(UserMediaRequest&amp; request)
</span><span class="lines">@@ -60,6 +64,16 @@
</span><span class="cx">     m_client-&gt;cancelUserMediaAccessRequest(request);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+inline void UserMediaController::checkUserMediaPermission(UserMediaPermissionCheck&amp; request)
+{
+    m_client-&gt;checkUserMediaPermission(request);
+}
+
+inline void UserMediaController::cancelUserMediaPermissionCheck(UserMediaPermissionCheck&amp; request)
+{
+    m_client-&gt;cancelUserMediaPermissionCheck(request);
+}
+
</ins><span class="cx"> } // namespace WebCore
</span><span class="cx"> 
</span><span class="cx"> #endif // ENABLE(MEDIA_STREAM)
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesmediastreamUserMediaPermissionCheckcpp"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/Modules/mediastream/UserMediaPermissionCheck.cpp (0 => 193944)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/mediastream/UserMediaPermissionCheck.cpp                                (rev 0)
+++ trunk/Source/WebCore/Modules/mediastream/UserMediaPermissionCheck.cpp        2015-12-11 04:06:05 UTC (rev 193944)
</span><span class="lines">@@ -0,0 +1,93 @@
</span><ins>+/*
+ * Copyright (C) 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
+ * 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. ``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
+ * 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 &quot;config.h&quot;
+#include &quot;UserMediaPermissionCheck.h&quot;
+
+#if ENABLE(MEDIA_STREAM)
+
+#include &quot;Document.h&quot;
+#include &quot;ExceptionCode.h&quot;
+#include &quot;Frame.h&quot;
+#include &quot;JSMediaDeviceInfo.h&quot;
+#include &quot;RealtimeMediaSourceCenter.h&quot;
+#include &quot;SecurityOrigin.h&quot;
+#include &quot;UserMediaController.h&quot;
+#include &lt;wtf/MainThread.h&gt;
+
+namespace WebCore {
+
+Ref&lt;UserMediaPermissionCheck&gt; UserMediaPermissionCheck::create(Document&amp; document, UserMediaPermissionCheckClient&amp; client)
+{
+    return adoptRef(*new UserMediaPermissionCheck(document, client));
+}
+
+UserMediaPermissionCheck::UserMediaPermissionCheck(ScriptExecutionContext&amp; context, UserMediaPermissionCheckClient&amp; client)
+    : ContextDestructionObserver(&amp;context)
+    , m_client(&amp;client)
+{
+}
+
+UserMediaPermissionCheck::~UserMediaPermissionCheck()
+{
+}
+
+SecurityOrigin* UserMediaPermissionCheck::securityOrigin() const
+{
+    if (scriptExecutionContext())
+        return scriptExecutionContext()-&gt;securityOrigin();
+
+    return nullptr;
+}
+
+void UserMediaPermissionCheck::contextDestroyed()
+{
+    ContextDestructionObserver::contextDestroyed();
+}
+
+void UserMediaPermissionCheck::start()
+{
+    ASSERT(scriptExecutionContext());
+
+    auto&amp; document = downcast&lt;Document&gt;(*scriptExecutionContext());
+    UserMediaController* controller = UserMediaController::from(document.page());
+    if (!controller)
+        return;
+
+    controller-&gt;checkUserMediaPermission(*this);
+}
+
+void UserMediaPermissionCheck::setHasPersistentPermission(bool mode)
+{
+    m_hasPersistentPermission = mode;
+
+    if (m_client)
+        m_client-&gt;didCompleteCheck(m_hasPersistentPermission);
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(MEDIA_STREAM)
</ins></span></pre></div>
<a id="trunkSourceWebCoreModulesmediastreamUserMediaPermissionCheckh"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/Modules/mediastream/UserMediaPermissionCheck.h (0 => 193944)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/mediastream/UserMediaPermissionCheck.h                                (rev 0)
+++ trunk/Source/WebCore/Modules/mediastream/UserMediaPermissionCheck.h        2015-12-11 04:06:05 UTC (rev 193944)
</span><span class="lines">@@ -0,0 +1,76 @@
</span><ins>+/*
+ * Copyright (C) 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
+ * 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. ``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
+ * 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 UserMediaPermissionCheck_h
+#define UserMediaPermissionCheck_h
+
+#if ENABLE(MEDIA_STREAM)
+
+#include &quot;ActiveDOMObject.h&quot;
+#include &quot;MediaDevices.h&quot;
+#include &lt;wtf/RefCounted.h&gt;
+#include &lt;wtf/text/WTFString.h&gt;
+
+namespace WebCore {
+
+class Document;
+class SecurityOrigin;
+
+class UserMediaPermissionCheckClient {
+public:
+    virtual ~UserMediaPermissionCheckClient() { }
+
+    virtual void didCompleteCheck(bool) = 0;
+};
+
+class UserMediaPermissionCheck final : public ContextDestructionObserver, public RefCounted&lt;UserMediaPermissionCheck&gt; {
+public:
+    static Ref&lt;UserMediaPermissionCheck&gt; create(Document&amp;, UserMediaPermissionCheckClient&amp;);
+
+    virtual ~UserMediaPermissionCheck();
+
+    void start();
+    void setClient(UserMediaPermissionCheckClient* client) { m_client = client; }
+
+    WEBCORE_EXPORT void setHasPersistentPermission(bool);
+
+    WEBCORE_EXPORT SecurityOrigin* securityOrigin() const;
+
+private:
+    UserMediaPermissionCheck(ScriptExecutionContext&amp;, UserMediaPermissionCheckClient&amp;);
+
+    // ContextDestructionObserver
+    virtual void contextDestroyed() override final;
+
+    UserMediaPermissionCheckClient* m_client;
+    bool m_hasPersistentPermission { false };
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(MEDIA_STREAM)
+
+#endif // UserMediaPermissionCheck_h
</ins></span></pre></div>
<a id="trunkSourceWebCoreWebCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (193943 => 193944)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2015-12-11 04:03:28 UTC (rev 193943)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2015-12-11 04:06:05 UTC (rev 193944)
</span><span class="lines">@@ -130,6 +130,8 @@
</span><span class="cx">                 07277E5317D018CC0015534D /* JSMediaStreamTrack.h in Headers */ = {isa = PBXBuildFile; fileRef = 07277E4717D018CC0015534D /* JSMediaStreamTrack.h */; };
</span><span class="cx">                 07277E5417D018CC0015534D /* JSMediaStreamTrackEvent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 07277E4817D018CC0015534D /* JSMediaStreamTrackEvent.cpp */; };
</span><span class="cx">                 07277E5517D018CC0015534D /* JSMediaStreamTrackEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 07277E4917D018CC0015534D /* JSMediaStreamTrackEvent.h */; };
</span><ins>+                07297FA71C1881C5003F0735 /* UserMediaPermissionCheck.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 07297FA51C1881C5003F0735 /* UserMediaPermissionCheck.cpp */; settings = {ASSET_TAGS = (); }; };
+                07297FA81C1881C5003F0735 /* UserMediaPermissionCheck.h in Headers */ = {isa = PBXBuildFile; fileRef = 07297FA61C1881C5003F0735 /* UserMediaPermissionCheck.h */; settings = {ATTRIBUTES = (Private, ); }; };
</ins><span class="cx">                 072AE1E5183C0741000A5988 /* PluginReplacement.h in Headers */ = {isa = PBXBuildFile; fileRef = 072AE1DF183C0741000A5988 /* PluginReplacement.h */; };
</span><span class="cx">                 072AE1E6183C0741000A5988 /* QuickTimePluginReplacement.mm in Sources */ = {isa = PBXBuildFile; fileRef = 072AE1E0183C0741000A5988 /* QuickTimePluginReplacement.mm */; };
</span><span class="cx">                 072AE1E8183C0741000A5988 /* QuickTimePluginReplacement.h in Headers */ = {isa = PBXBuildFile; fileRef = 072AE1E2183C0741000A5988 /* QuickTimePluginReplacement.h */; };
</span><span class="lines">@@ -154,7 +156,7 @@
</span><span class="cx">                 073794FD19F5864E00E5A045 /* RTCNotifiersMock.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 073794F719F5864E00E5A045 /* RTCNotifiersMock.cpp */; };
</span><span class="cx">                 073794FE19F5864E00E5A045 /* RTCNotifiersMock.h in Headers */ = {isa = PBXBuildFile; fileRef = 073794F819F5864E00E5A045 /* RTCNotifiersMock.h */; };
</span><span class="cx">                 07394EC81BAB2CCD00BE99CD /* MediaDevicesRequest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 07394EC71BAB2CCD00BE99CD /* MediaDevicesRequest.cpp */; };
</span><del>-                07394ECA1BAB2CD700BE99CD /* MediaDevicesRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = 07394EC91BAB2CD700BE99CD /* MediaDevicesRequest.h */; };
</del><ins>+                07394ECA1BAB2CD700BE99CD /* MediaDevicesRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = 07394EC91BAB2CD700BE99CD /* MediaDevicesRequest.h */; settings = {ATTRIBUTES = (Private, ); }; };
</ins><span class="cx">                 073BE34017D17E01002BD431 /* JSNavigatorUserMedia.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 073BE33E17D17E01002BD431 /* JSNavigatorUserMedia.cpp */; };
</span><span class="cx">                 073BE34117D17E01002BD431 /* JSNavigatorUserMedia.h in Headers */ = {isa = PBXBuildFile; fileRef = 073BE33F17D17E01002BD431 /* JSNavigatorUserMedia.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 073BE34817D17E7A002BD431 /* JSNavigatorUserMediaError.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 073BE34217D17E7A002BD431 /* JSNavigatorUserMediaError.cpp */; };
</span><span class="lines">@@ -167,8 +169,6 @@
</span><span class="cx">                 0753860214489E9800B78452 /* CachedTextTrack.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0753860014489E9800B78452 /* CachedTextTrack.cpp */; };
</span><span class="cx">                 0753860314489E9800B78452 /* CachedTextTrack.h in Headers */ = {isa = PBXBuildFile; fileRef = 0753860114489E9800B78452 /* CachedTextTrack.h */; };
</span><span class="cx">                 076306D017E1478D005A7C4E /* MediaStreamTrackSourcesCallback.h in Headers */ = {isa = PBXBuildFile; fileRef = 076306CC17E1478D005A7C4E /* MediaStreamTrackSourcesCallback.h */; };
</span><del>-                076306D217E1478D005A7C4E /* MediaStreamTrackSourcesRequest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 076306CE17E1478D005A7C4E /* MediaStreamTrackSourcesRequest.cpp */; };
-                076306D317E1478D005A7C4E /* MediaStreamTrackSourcesRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = 076306CF17E1478D005A7C4E /* MediaStreamTrackSourcesRequest.h */; };
</del><span class="cx">                 076306D717E149CF005A7C4E /* SourceInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 076306D417E149CF005A7C4E /* SourceInfo.cpp */; };
</span><span class="cx">                 076306D817E149D0005A7C4E /* SourceInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 076306D517E149CF005A7C4E /* SourceInfo.h */; };
</span><span class="cx">                 076306DC17E15FB0005A7C4E /* JSMediaStreamTrackSourcesCallback.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 076306DA17E15FB0005A7C4E /* JSMediaStreamTrackSourcesCallback.cpp */; };
</span><span class="lines">@@ -1148,7 +1148,6 @@
</span><span class="cx">                 2D77AC2B1BF2B9870072470A /* NSTextFinderSPI.h in Headers */ = {isa = PBXBuildFile; fileRef = 2D77AC281BF2B9860072470A /* NSTextFinderSPI.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 2D77AC2D1BF2B9A00072470A /* NSViewSPI.h in Headers */ = {isa = PBXBuildFile; fileRef = 2D77AC2C1BF2B9A00072470A /* NSViewSPI.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 2D7ED0AB1BAE99170043B3E5 /* TimerEventBasedMock.h in Headers */ = {isa = PBXBuildFile; fileRef = 2D7ED0A91BAE99170043B3E5 /* TimerEventBasedMock.h */; };
</span><del>-                2D7ED0AC1BAE99170043B3E5 /* UserMediaClientMock.h in Headers */ = {isa = PBXBuildFile; fileRef = 2D7ED0AA1BAE99170043B3E5 /* UserMediaClientMock.h */; };
</del><span class="cx">                 2D8287F616E4A0380086BD00 /* HitTestLocation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2D8287F416E4A0380086BD00 /* HitTestLocation.cpp */; };
</span><span class="cx">                 2D8287F716E4A0380086BD00 /* HitTestLocation.h in Headers */ = {isa = PBXBuildFile; fileRef = 2D8287F516E4A0380086BD00 /* HitTestLocation.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 2D8FEBDC143E3EF70072502B /* CSSCrossfadeValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2D8FEBDA143E3EF70072502B /* CSSCrossfadeValue.cpp */; };
</span><span class="lines">@@ -7438,6 +7437,8 @@
</span><span class="cx">                 07277E4817D018CC0015534D /* JSMediaStreamTrackEvent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSMediaStreamTrackEvent.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 07277E4917D018CC0015534D /* JSMediaStreamTrackEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSMediaStreamTrackEvent.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 072847E216EBC5B00043CFA4 /* PlatformTextTrack.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PlatformTextTrack.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                07297FA51C1881C5003F0735 /* UserMediaPermissionCheck.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = UserMediaPermissionCheck.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                07297FA61C1881C5003F0735 /* UserMediaPermissionCheck.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UserMediaPermissionCheck.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 072AE1DF183C0741000A5988 /* PluginReplacement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PluginReplacement.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 072AE1E0183C0741000A5988 /* QuickTimePluginReplacement.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = QuickTimePluginReplacement.mm; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 072AE1E1183C0741000A5988 /* QuickTimePluginReplacement.css */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.css; path = QuickTimePluginReplacement.css; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -7477,8 +7478,6 @@
</span><span class="cx">                 0753860114489E9800B78452 /* CachedTextTrack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CachedTextTrack.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 076306CC17E1478D005A7C4E /* MediaStreamTrackSourcesCallback.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MediaStreamTrackSourcesCallback.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 076306CD17E1478D005A7C4E /* MediaStreamTrackSourcesCallback.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = MediaStreamTrackSourcesCallback.idl; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><del>-                076306CE17E1478D005A7C4E /* MediaStreamTrackSourcesRequest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MediaStreamTrackSourcesRequest.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
-                076306CF17E1478D005A7C4E /* MediaStreamTrackSourcesRequest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MediaStreamTrackSourcesRequest.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</del><span class="cx">                 076306D417E149CF005A7C4E /* SourceInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SourceInfo.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 076306D517E149CF005A7C4E /* SourceInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SourceInfo.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 076306D617E149CF005A7C4E /* SourceInfo.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = SourceInfo.idl; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -8499,7 +8498,6 @@
</span><span class="cx">                 2D77AC281BF2B9860072470A /* NSTextFinderSPI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NSTextFinderSPI.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 2D77AC2C1BF2B9A00072470A /* NSViewSPI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NSViewSPI.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 2D7ED0A91BAE99170043B3E5 /* TimerEventBasedMock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TimerEventBasedMock.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><del>-                2D7ED0AA1BAE99170043B3E5 /* UserMediaClientMock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UserMediaClientMock.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</del><span class="cx">                 2D8287F416E4A0380086BD00 /* HitTestLocation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HitTestLocation.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 2D8287F516E4A0380086BD00 /* HitTestLocation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HitTestLocation.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 2D8FEBDA143E3EF70072502B /* CSSCrossfadeValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CSSCrossfadeValue.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -15126,8 +15124,6 @@
</span><span class="cx">                                 07221B5917CEC32700848E51 /* MediaStreamTrackEvent.idl */,
</span><span class="cx">                                 076306CC17E1478D005A7C4E /* MediaStreamTrackSourcesCallback.h */,
</span><span class="cx">                                 076306CD17E1478D005A7C4E /* MediaStreamTrackSourcesCallback.idl */,
</span><del>-                                076306CE17E1478D005A7C4E /* MediaStreamTrackSourcesRequest.cpp */,
-                                076306CF17E1478D005A7C4E /* MediaStreamTrackSourcesRequest.h */,
</del><span class="cx">                                 0705853917FE0770005F2BCB /* MediaTrackConstraint.cpp */,
</span><span class="cx">                                 0705851D17FDC140005F2BCB /* MediaTrackConstraint.h */,
</span><span class="cx">                                 0705851E17FDC140005F2BCB /* MediaTrackConstraint.idl */,
</span><span class="lines">@@ -15204,6 +15200,8 @@
</span><span class="cx">                                 07221B8D17CEC32700848E51 /* UserMediaClient.h */,
</span><span class="cx">                                 07221B8E17CEC32700848E51 /* UserMediaController.cpp */,
</span><span class="cx">                                 07221B8F17CEC32700848E51 /* UserMediaController.h */,
</span><ins>+                                07297FA51C1881C5003F0735 /* UserMediaPermissionCheck.cpp */,
+                                07297FA61C1881C5003F0735 /* UserMediaPermissionCheck.h */,
</ins><span class="cx">                                 07221B9017CEC32700848E51 /* UserMediaRequest.cpp */,
</span><span class="cx">                                 07221B9117CEC32700848E51 /* UserMediaRequest.h */,
</span><span class="cx">                         );
</span><span class="lines">@@ -17151,7 +17149,6 @@
</span><span class="cx">                                 0FE71403142170B800DB33BA /* ScrollbarThemeMock.cpp */,
</span><span class="cx">                                 0FE71404142170B800DB33BA /* ScrollbarThemeMock.h */,
</span><span class="cx">                                 2D7ED0A91BAE99170043B3E5 /* TimerEventBasedMock.h */,
</span><del>-                                2D7ED0AA1BAE99170043B3E5 /* UserMediaClientMock.h */,
</del><span class="cx">                         );
</span><span class="cx">                         path = mock;
</span><span class="cx">                         sourceTree = &quot;&lt;group&gt;&quot;;
</span><span class="lines">@@ -26195,6 +26192,7 @@
</span><span class="cx">                                 CDAB6D2E17C814EE00C60B34 /* JSMediaControlsHost.h in Headers */,
</span><span class="cx">                                 159741DB1B7D140100201C92 /* JSMediaDeviceInfo.h in Headers */,
</span><span class="cx">                                 15739BBB1B42012D00D258C1 /* JSMediaDevices.h in Headers */,
</span><ins>+                                07297FA81C1881C5003F0735 /* UserMediaPermissionCheck.h in Headers */,
</ins><span class="cx">                                 FD23A12613F5FA5900F67001 /* JSMediaElementAudioSourceNode.h in Headers */,
</span><span class="cx">                                 E44614190CD6826900FADA75 /* JSMediaError.h in Headers */,
</span><span class="cx">                                 BC3C39B70C0D3D8D005F4D7A /* JSMediaList.h in Headers */,
</span><span class="lines">@@ -26704,7 +26702,6 @@
</span><span class="cx">                                 078E091917D14D1C00420AA1 /* MediaStreamTrackEvent.h in Headers */,
</span><span class="cx">                                 07FFDE69181AED420072D409 /* MediaStreamTrackPrivate.h in Headers */,
</span><span class="cx">                                 076306D017E1478D005A7C4E /* MediaStreamTrackSourcesCallback.h in Headers */,
</span><del>-                                076306D317E1478D005A7C4E /* MediaStreamTrackSourcesRequest.h in Headers */,
</del><span class="cx">                                 076306E317E22A43005A7C4E /* MediaStreamTrackSourcesRequestClient.h in Headers */,
</span><span class="cx">                                 CD641EC01819B36000EE4C41 /* MediaTimeAVFoundation.h in Headers */,
</span><span class="cx">                                 CD60C0C7193E87C7003C656B /* MediaTimeQTKit.h in Headers */,
</span><span class="lines">@@ -27893,7 +27890,6 @@
</span><span class="cx">                                 2542F4DB1166C25A00E89A86 /* UserGestureIndicator.h in Headers */,
</span><span class="cx">                                 9920398318B95BC600B39AF9 /* UserInputBridge.h in Headers */,
</span><span class="cx">                                 078E092E17D14D1C00420AA1 /* UserMediaClient.h in Headers */,
</span><del>-                                2D7ED0AC1BAE99170043B3E5 /* UserMediaClientMock.h in Headers */,
</del><span class="cx">                                 078E092F17D14D1C00420AA1 /* UserMediaController.h in Headers */,
</span><span class="cx">                                 078E093017D14D1C00420AA1 /* UserMediaRequest.h in Headers */,
</span><span class="cx">                                 7C3B79721908757B00B47A2D /* UserMessageHandler.h in Headers */,
</span><span class="lines">@@ -29687,6 +29683,7 @@
</span><span class="cx">                                 517139051BF64DEC000D5F01 /* MemoryObjectStoreCursor.cpp in Sources */,
</span><span class="cx">                                 4ACBC0CA12713D0A0094F9B2 /* JSDOMSettableTokenList.cpp in Sources */,
</span><span class="cx">                                 C5137CF211A58378004ADB99 /* JSDOMStringList.cpp in Sources */,
</span><ins>+                                07297FA71C1881C5003F0735 /* UserMediaPermissionCheck.cpp in Sources */,
</ins><span class="cx">                                 9A1B6F97158869C80011A8C4 /* JSDOMStringListCustom.cpp in Sources */,
</span><span class="cx">                                 BC64649711D82349006455B0 /* JSDOMStringMap.cpp in Sources */,
</span><span class="cx">                                 BC64649C11D8238C006455B0 /* JSDOMStringMapCustom.cpp in Sources */,
</span><span class="lines">@@ -30399,7 +30396,6 @@
</span><span class="cx">                                 078E090217D14CEE00420AA1 /* MediaStreamTrack.cpp in Sources */,
</span><span class="cx">                                 078E090317D14CEE00420AA1 /* MediaStreamTrackEvent.cpp in Sources */,
</span><span class="cx">                                 07FFDE68181AED420072D409 /* MediaStreamTrackPrivate.cpp in Sources */,
</span><del>-                                076306D217E1478D005A7C4E /* MediaStreamTrackSourcesRequest.cpp in Sources */,
</del><span class="cx">                                 CD641EBF1819B36000EE4C41 /* MediaTimeAVFoundation.cpp in Sources */,
</span><span class="cx">                                 CD60C0C6193E87C7003C656B /* MediaTimeQTKit.mm in Sources */,
</span><span class="cx">                                 0705853A17FE0770005F2BCB /* MediaTrackConstraint.cpp in Sources */,
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformmockUserMediaClientMockh"></a>
<div class="delfile"><h4>Deleted: trunk/Source/WebCore/platform/mock/UserMediaClientMock.h (193943 => 193944)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/mock/UserMediaClientMock.h        2015-12-11 04:03:28 UTC (rev 193943)
+++ trunk/Source/WebCore/platform/mock/UserMediaClientMock.h        2015-12-11 04:06:05 UTC (rev 193944)
</span><span class="lines">@@ -1,90 +0,0 @@
</span><del>-/*
- *  Copyright (C) 2013 Nokia Corporation and/or its subsidiary(-ies).
- *
- * 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * &quot;AS IS&quot; 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 THE COPYRIGHT
- * OWNER OR 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 UserMediaClientMock_h
-#define UserMediaClientMock_h
-
-#if ENABLE(MEDIA_STREAM)
-
-#include &quot;TimerEventBasedMock.h&quot;
-#include &quot;UserMediaClient.h&quot;
-#include &quot;UserMediaRequest.h&quot;
-
-namespace WebCore {
-
-class UserMediaClientRequestNotifier : public MockNotifier {
-public:
-    UserMediaClientRequestNotifier(Ref&lt;UserMediaRequest&gt;&amp;&amp; request, bool requestSuccess)
-        : m_request(WTF::move(request))
-        , m_requestSuccess(requestSuccess)
-    {
-    }
-
-    void fire() override
-    {
-        if (!m_requestSuccess) {
-            m_request-&gt;userMediaAccessDenied();
-            return;
-        }
-
-        auto audioDeviceUIDs = m_request-&gt;audioDeviceUIDs();
-        auto videoDeviceUIDs  = m_request-&gt;videoDeviceUIDs();
-        String allowedAudioUID = audioDeviceUIDs.size() ? audioDeviceUIDs.at(0) : emptyString();
-        String videoAudioUID = videoDeviceUIDs.size() ? videoDeviceUIDs.at(0) : emptyString();
-
-        m_request-&gt;userMediaAccessGranted(allowedAudioUID, videoAudioUID);
-    }
-
-private:
-    Ref&lt;UserMediaRequest&gt; m_request;
-    bool m_requestSuccess;
-};
-
-class UserMediaClientMock final : public UserMediaClient, public TimerEventBasedMock {
-public:
-    public:
-    virtual void pageDestroyed() override
-    {
-        delete this;
-    }
-
-    virtual void requestUserMediaAccess(Ref&lt;UserMediaRequest&gt;&amp;&amp; request) override
-    {
-        RefPtr&lt;UserMediaClientRequestNotifier&gt; notifier = adoptRef(new UserMediaClientRequestNotifier(WTF::move(request), true));
-        m_timerEvents.append(adoptRef(new TimerEvent(this, notifier)));
-    }
-
-    virtual void cancelUserMediaAccessRequest(UserMediaRequest&amp; request) override
-    {
-        RefPtr&lt;UserMediaClientRequestNotifier&gt; notifier = adoptRef(new UserMediaClientRequestNotifier(request, false));
-        m_timerEvents.append(adoptRef(new TimerEvent(this, notifier)));
-    }
-};
-
-} // namespace WebCore
-
-#endif // ENABLE(MEDIA_STREAM)
-
-#endif // UserMediaClientMock_h
</del></span></pre></div>
<a id="trunkSourceWebCoretestingInternalscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/testing/Internals.cpp (193943 => 193944)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/testing/Internals.cpp        2015-12-11 04:03:28 UTC (rev 193943)
+++ trunk/Source/WebCore/testing/Internals.cpp        2015-12-11 04:06:05 UTC (rev 193944)
</span><span class="lines">@@ -171,7 +171,6 @@
</span><span class="cx"> #include &quot;MockRealtimeMediaSourceCenter.h&quot;
</span><span class="cx"> #include &quot;RTCPeerConnection.h&quot;
</span><span class="cx"> #include &quot;RTCPeerConnectionHandlerMock.h&quot;
</span><del>-#include &quot;UserMediaClientMock.h&quot;
</del><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(MEDIA_SOURCE)
</span></span></pre></div>
<a id="trunkSourceWebKitmacChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/mac/ChangeLog (193943 => 193944)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/mac/ChangeLog        2015-12-11 04:03:28 UTC (rev 193943)
+++ trunk/Source/WebKit/mac/ChangeLog        2015-12-11 04:06:05 UTC (rev 193944)
</span><span class="lines">@@ -1,3 +1,36 @@
</span><ins>+2015-12-10  Eric Carlson  &lt;eric.carlson@apple.com&gt;
+
+        [MediaStream] Expose media capture devices persistent permissions to WebCore
+        https://bugs.webkit.org/show_bug.cgi?id=152087
+
+        Reviewed by Chris Dumez.
+
+        Add methods and helpers for WK1 permission checker interface.
+        * WebCoreSupport/WebUserMediaClient.h:
+        * WebCoreSupport/WebUserMediaClient.mm:
+        (userMediaRequestsMap):
+        (AddRequestToRequestMap):
+        (RemoveRequestFromRequestMap):
+        (userMediaCheckMap):
+        (AddPermissionCheckToMap):
+        (RemovePermissionCheckFromMap):
+        (WebUserMediaClient::WebUserMediaClient):
+        (WebUserMediaClient::requestUserMediaAccess):
+        (WebUserMediaClient::cancelUserMediaAccessRequest):
+        (WebUserMediaClient::checkUserMediaPermission):
+        (WebUserMediaClient::cancelUserMediaPermissionCheck):
+        (-[WebUserMediaPolicyListener allow]):
+        (-[WebUserMediaPolicyListener deny]):
+        (-[WebUserMediaPolicyCheckerListener initWithUserMediaPermissionCheck:]):
+        (-[WebUserMediaPolicyCheckerListener cancelUserMediaPermissionCheck]):
+        (-[WebUserMediaPolicyCheckerListener allow]):
+        (-[WebUserMediaPolicyCheckerListener deny]):
+        (-[WebUserMediaPolicyCheckerListener denyOnlyThisRequest]):
+        (-[WebUserMediaPolicyCheckerListener shouldClearCache]):
+        (AddRequestToMap): Deleted.
+        (RemoveRequestFromMap): Deleted.
+        * WebView/WebUIDelegatePrivate.h:
+
</ins><span class="cx"> 2015-12-08  Beth Dakin  &lt;bdakin@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Follow-up to:
</span></span></pre></div>
<a id="trunkSourceWebKitmacWebCoreSupportWebUserMediaClienth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/mac/WebCoreSupport/WebUserMediaClient.h (193943 => 193944)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/mac/WebCoreSupport/WebUserMediaClient.h        2015-12-11 04:03:28 UTC (rev 193943)
+++ trunk/Source/WebKit/mac/WebCoreSupport/WebUserMediaClient.h        2015-12-11 04:06:05 UTC (rev 193944)
</span><span class="lines">@@ -33,6 +33,7 @@
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> class UserMediaClient;
</span><ins>+class UserMediaPermissionCheck;
</ins><span class="cx"> class UserMediaRequest;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -44,10 +45,14 @@
</span><span class="cx">     ~WebUserMediaClient();
</span><span class="cx"> 
</span><span class="cx">     // UserMediaClient
</span><del>-    virtual void requestUserMediaAccess(Ref&lt;WebCore::UserMediaRequest&gt;&amp;&amp;) override;
-    virtual void cancelUserMediaAccessRequest(WebCore::UserMediaRequest&amp;) override;
-    virtual void pageDestroyed() override;
</del><ins>+    void requestUserMediaAccess(WebCore::UserMediaRequest&amp;) override;
+    void cancelUserMediaAccessRequest(WebCore::UserMediaRequest&amp;) override;
</ins><span class="cx"> 
</span><ins>+    void checkUserMediaPermission(WebCore::UserMediaPermissionCheck&amp;) override;
+    void cancelUserMediaPermissionCheck(WebCore::UserMediaPermissionCheck&amp;) override;
+
+    void pageDestroyed() override;
+
</ins><span class="cx"> private:
</span><span class="cx">     WebView* m_webView;
</span><span class="cx"> };
</span></span></pre></div>
<a id="trunkSourceWebKitmacWebCoreSupportWebUserMediaClientmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/mac/WebCoreSupport/WebUserMediaClient.mm (193943 => 193944)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/mac/WebCoreSupport/WebUserMediaClient.mm        2015-12-11 04:03:28 UTC (rev 193943)
+++ trunk/Source/WebKit/mac/WebCoreSupport/WebUserMediaClient.mm        2015-12-11 04:06:05 UTC (rev 193944)
</span><span class="lines">@@ -34,8 +34,10 @@
</span><span class="cx"> #import &lt;WebCore/BlockExceptions.h&gt;
</span><span class="cx"> #import &lt;WebCore/Page.h&gt;
</span><span class="cx"> #import &lt;WebCore/ScriptExecutionContext.h&gt;
</span><ins>+#import &lt;WebCore/UserMediaPermissionCheck.h&gt;
</ins><span class="cx"> #import &lt;WebCore/UserMediaRequest.h&gt;
</span><span class="cx"> #import &lt;wtf/HashMap.h&gt;
</span><ins>+#import &lt;wtf/NeverDestroyed.h&gt;
</ins><span class="cx"> #import &lt;wtf/RefPtr.h&gt;
</span><span class="cx"> #import &lt;wtf/RetainPtr.h&gt;
</span><span class="cx"> 
</span><span class="lines">@@ -50,24 +52,51 @@
</span><span class="cx"> - (void)deny;
</span><span class="cx"> @end
</span><span class="cx"> 
</span><ins>+@interface WebUserMediaPolicyCheckerListener : NSObject &lt;WebAllowDenyPolicyListener&gt; {
+    RefPtr&lt;UserMediaPermissionCheck&gt; _request;
+}
+- (id)initWithUserMediaPermissionCheck:(PassRefPtr&lt;UserMediaPermissionCheck&gt;)request;
+- (void)cancelUserMediaPermissionCheck;
+- (void)deny;
+@end
+
</ins><span class="cx"> typedef HashMap&lt;RefPtr&lt;UserMediaRequest&gt;, RetainPtr&lt;WebUserMediaPolicyListener&gt;&gt; UserMediaRequestsMap;
</span><span class="cx"> 
</span><span class="cx"> static UserMediaRequestsMap&amp; userMediaRequestsMap()
</span><span class="cx"> {
</span><del>-    DEPRECATED_DEFINE_STATIC_LOCAL(UserMediaRequestsMap, requests, ());
</del><ins>+    static NeverDestroyed&lt;UserMediaRequestsMap&gt; requests;
</ins><span class="cx">     return requests;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static void AddRequestToMap(UserMediaRequest* request, RetainPtr&lt;WebUserMediaPolicyListener&gt; listener)
</del><ins>+static void AddRequestToRequestMap(UserMediaRequest* request, RetainPtr&lt;WebUserMediaPolicyListener&gt; listener)
</ins><span class="cx"> {
</span><span class="cx">     userMediaRequestsMap().set(request, listener);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static void RemoveRequestFromMap(UserMediaRequest* request)
</del><ins>+static void RemoveRequestFromRequestMap(UserMediaRequest* request)
</ins><span class="cx"> {
</span><span class="cx">     userMediaRequestsMap().remove(request);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+typedef HashMap&lt;RefPtr&lt;UserMediaPermissionCheck&gt;, RetainPtr&lt;WebUserMediaPolicyCheckerListener&gt;&gt; UserMediaCheckMap;
+
+static UserMediaCheckMap&amp; userMediaCheckMap()
+{
+    DEPRECATED_DEFINE_STATIC_LOCAL(UserMediaCheckMap, requests, ());
+    return requests;
+}
+
+static void AddPermissionCheckToMap(UserMediaPermissionCheck* request, RetainPtr&lt;WebUserMediaPolicyCheckerListener&gt; listener)
+{
+    userMediaCheckMap().set(request, listener);
+}
+
+static void RemovePermissionCheckFromMap(UserMediaPermissionCheck* request)
+{
+    userMediaCheckMap().remove(request);
+}
+
+
</ins><span class="cx"> WebUserMediaClient::WebUserMediaClient(WebView* webView)
</span><span class="cx">     : m_webView(webView)
</span><span class="cx"> {
</span><span class="lines">@@ -88,22 +117,21 @@
</span><span class="cx">     delete this;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void WebUserMediaClient::requestUserMediaAccess(Ref&lt;UserMediaRequest&gt;&amp;&amp; prpRequest)
</del><ins>+void WebUserMediaClient::requestUserMediaAccess(UserMediaRequest&amp; request)
</ins><span class="cx"> {
</span><span class="cx">     BEGIN_BLOCK_OBJC_EXCEPTIONS;
</span><span class="cx"> 
</span><del>-    UserMediaRequest* request = &amp;prpRequest.get();
</del><span class="cx">     SEL selector = @selector(webView:decidePolicyForUserMediaRequestFromOrigin:listener:);
</span><span class="cx">     if (![[m_webView UIDelegate] respondsToSelector:selector]) {
</span><del>-        request-&gt;userMediaAccessDenied();
</del><ins>+        request.userMediaAccessDenied();
</ins><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    WebUserMediaPolicyListener *listener = [[WebUserMediaPolicyListener alloc] initWithUserMediaRequest:request];
-    WebSecurityOrigin *webOrigin = [[WebSecurityOrigin alloc] _initWithWebCoreSecurityOrigin:request-&gt;securityOrigin()];
</del><ins>+    WebUserMediaPolicyListener *listener = [[WebUserMediaPolicyListener alloc] initWithUserMediaRequest:&amp;request];
+    WebSecurityOrigin *webOrigin = [[WebSecurityOrigin alloc] _initWithWebCoreSecurityOrigin:request.securityOrigin()];
</ins><span class="cx"> 
</span><span class="cx">     CallUIDelegate(m_webView, selector, webOrigin, listener);
</span><del>-    AddRequestToMap(request, listener);
</del><ins>+    AddRequestToRequestMap(&amp;request, listener);
</ins><span class="cx"> 
</span><span class="cx">     [webOrigin release];
</span><span class="cx">     [listener release];
</span><span class="lines">@@ -122,7 +150,40 @@
</span><span class="cx">     requestsMap.remove(it);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void WebUserMediaClient::checkUserMediaPermission(UserMediaPermissionCheck&amp; request)
+{
+    BEGIN_BLOCK_OBJC_EXCEPTIONS;
</ins><span class="cx"> 
</span><ins>+    SEL selector = @selector(webView:checkPolicyForUserMediaRequestFromOrigin:listener:);
+    if (![[m_webView UIDelegate] respondsToSelector:selector]) {
+        request.setHasPersistentPermission(false);
+        return;
+    }
+
+    WebUserMediaPolicyCheckerListener *listener = [[WebUserMediaPolicyCheckerListener alloc] initWithUserMediaPermissionCheck:&amp;request];
+    WebSecurityOrigin *webOrigin = [[WebSecurityOrigin alloc] _initWithWebCoreSecurityOrigin:request.securityOrigin()];
+
+    CallUIDelegate(m_webView, selector, webOrigin, listener);
+    AddPermissionCheckToMap(&amp;request, listener);
+
+    [webOrigin release];
+    [listener release];
+
+    END_BLOCK_OBJC_EXCEPTIONS;
+}
+
+
+void WebUserMediaClient::cancelUserMediaPermissionCheck(WebCore::UserMediaPermissionCheck&amp; request)
+{
+    UserMediaCheckMap&amp; requestsMap = userMediaCheckMap();
+    UserMediaCheckMap::iterator it = requestsMap.find(&amp;request);
+    if (it == requestsMap.end())
+        return;
+
+    [it-&gt;value cancelUserMediaPermissionCheck];
+    requestsMap.remove(it);
+}
+
</ins><span class="cx"> @implementation WebUserMediaPolicyListener
</span><span class="cx"> 
</span><span class="cx"> - (id)initWithUserMediaRequest:(PassRefPtr&lt;UserMediaRequest&gt;)request
</span><span class="lines">@@ -155,7 +216,7 @@
</span><span class="cx">     
</span><span class="cx">     _request-&gt;userMediaAccessGranted(_request-&gt;allowedAudioDeviceUID(), _request-&gt;allowedVideoDeviceUID());
</span><span class="cx"> 
</span><del>-    RemoveRequestFromMap(_request.get());
</del><ins>+    RemoveRequestFromRequestMap(_request.get());
</ins><span class="cx"> #endif
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -166,7 +227,7 @@
</span><span class="cx">         return;
</span><span class="cx">     
</span><span class="cx">     _request-&gt;userMediaAccessDenied();
</span><del>-    RemoveRequestFromMap(_request.get());
</del><ins>+    RemoveRequestFromRequestMap(_request.get());
</ins><span class="cx"> #endif
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -184,4 +245,67 @@
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx"> @end
</span><ins>+
+
+@implementation WebUserMediaPolicyCheckerListener
+
+- (id)initWithUserMediaPermissionCheck:(PassRefPtr&lt;UserMediaPermissionCheck&gt;)request
+{
+#if ENABLE(MEDIA_STREAM)
+    if (!(self = [super init]))
+        return nil;
+
+    _request = request;
+    return self;
</ins><span class="cx"> #endif
</span><ins>+}
+
+- (void)cancelUserMediaPermissionCheck
+{
+#if ENABLE(MEDIA_STREAM)
+    if (!_request)
+        return;
+
+    _request = nullptr;
+#endif
+
+}
+
+- (void)allow
+{
+#if ENABLE(MEDIA_STREAM)
+    if (!_request)
+        return;
+
+    _request-&gt;setHasPersistentPermission(true);
+    RemovePermissionCheckFromMap(_request.get());
+#endif
+}
+
+- (void)deny
+{
+#if ENABLE(MEDIA_STREAM)
+    if (!_request)
+        return;
+
+    _request-&gt;setHasPersistentPermission(true);
+    RemovePermissionCheckFromMap(_request.get());
+#endif
+}
+
+#if PLATFORM(IOS)
+- (void)denyOnlyThisRequest
+{
+}
+
+- (BOOL)shouldClearCache
+{
+    // FIXME: https://bugs.webkit.org/show_bug.cgi?id=146245
+    ASSERT_NOT_REACHED();
+    return true;
+}
+#endif
+
+@end
+
+#endif // ENABLE(MEDIA_STREAM)
</ins></span></pre></div>
<a id="trunkSourceWebKitmacWebViewWebUIDelegatePrivateh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/mac/WebView/WebUIDelegatePrivate.h (193943 => 193944)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/mac/WebView/WebUIDelegatePrivate.h        2015-12-11 04:03:28 UTC (rev 193943)
+++ trunk/Source/WebKit/mac/WebView/WebUIDelegatePrivate.h        2015-12-11 04:06:05 UTC (rev 193944)
</span><span class="lines">@@ -258,6 +258,7 @@
</span><span class="cx"> - (void)webView:(WebView *)webView decidePolicyForNotificationRequestFromOrigin:(WebSecurityOrigin *)origin listener:(id&lt;WebAllowDenyPolicyListener&gt;)listener;
</span><span class="cx"> 
</span><span class="cx"> - (void)webView:(WebView *)webView decidePolicyForUserMediaRequestFromOrigin:(WebSecurityOrigin *)origin listener:(id&lt;WebAllowDenyPolicyListener&gt;)listener;
</span><ins>+- (void)webView:(WebView *)webView checkPolicyForUserMediaRequestFromOrigin:(WebSecurityOrigin *)origin listener:(id&lt;WebAllowDenyPolicyListener&gt;)listener;
</ins><span class="cx"> 
</span><span class="cx"> - (void)webView:(WebView *)sender elementDidFocusNode:(DOMNode *)node;
</span><span class="cx"> - (void)webView:(WebView *)sender elementDidBlurNode:(DOMNode *)node;
</span></span></pre></div>
<a id="trunkSourceWebKit2CMakeListstxt"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/CMakeLists.txt (193943 => 193944)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/CMakeLists.txt        2015-12-11 04:03:28 UTC (rev 193943)
+++ trunk/Source/WebKit2/CMakeLists.txt        2015-12-11 04:06:05 UTC (rev 193944)
</span><span class="lines">@@ -347,6 +347,7 @@
</span><span class="cx">     UIProcess/ResponsivenessTimer.cpp
</span><span class="cx">     UIProcess/StatisticsRequest.cpp
</span><span class="cx">     UIProcess/TextCheckerCompletion.cpp
</span><ins>+    UIProcess/UserMediaPermissionCheckProxy.cpp
</ins><span class="cx">     UIProcess/UserMediaPermissionRequestManagerProxy.cpp
</span><span class="cx">     UIProcess/UserMediaPermissionRequestProxy.cpp
</span><span class="cx">     UIProcess/VisitedLinkStore.cpp
</span><span class="lines">@@ -454,6 +455,7 @@
</span><span class="cx">     UIProcess/API/C/WKSessionStateRef.cpp
</span><span class="cx">     UIProcess/API/C/WKTextChecker.cpp
</span><span class="cx">     UIProcess/API/C/WKUserContentControllerRef.cpp
</span><ins>+    UIProcess/API/C/WKUserMediaPermissionCheck.cpp
</ins><span class="cx">     UIProcess/API/C/WKUserMediaPermissionRequest.cpp
</span><span class="cx">     UIProcess/API/C/WKVibration.cpp
</span><span class="cx">     UIProcess/API/C/WKViewportAttributes.cpp
</span></span></pre></div>
<a id="trunkSourceWebKit2ChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/ChangeLog (193943 => 193944)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/ChangeLog        2015-12-11 04:03:28 UTC (rev 193943)
+++ trunk/Source/WebKit2/ChangeLog        2015-12-11 04:06:05 UTC (rev 193944)
</span><span class="lines">@@ -1,3 +1,81 @@
</span><ins>+2015-12-10  Eric Carlson  &lt;eric.carlson@apple.com&gt;
+
+        [MediaStream] Expose media capture devices persistent permissions to WebCore
+        https://bugs.webkit.org/show_bug.cgi?id=152087
+
+        Reviewed by Chris Dumez.
+
+        * CMakeLists.txt: Add UserMediaPermissionCheckProxy.cpp and WKUserMediaPermissionCheck.cpp.
+
+        * Shared/API/APIObject.h: Define UserMediaPermissionCheck.
+
+        * Shared/API/c/WKBase.h: Add WKUserMediaPermissionCheckRef typedef.
+
+        * UIProcess/API/APIUIClient.h:
+        (API::UIClient::checkUserMediaPermissionForOrigin): New.
+
+        * UIProcess/API/C/WKAPICast.h: Add WKUserMediaPermissionCheckRef/UserMediaPermissionCheckProxy mapping.
+
+        * UIProcess/API/C/WKPage.cpp:
+        (WKPageSetPageUIClient): Implement checkUserMediaPermissionForOrigin.
+
+        * UIProcess/API/C/WKPageUIClient.h: Add WKCheckUserMediaPermissionCallback typedef and add
+          checkUserMediaPermissionForOrigin to WKPageUIClientV6.
+
+        * UIProcess/API/C/WKUserMediaPermissionCheck.cpp: Added.
+        (WKUserMediaPermissionCheckGetTypeID):
+        (WKUserMediaPermissionCheckSetHasPermission):
+
+        * UIProcess/API/C/WKUserMediaPermissionCheck.h: Added.
+
+        * UIProcess/UserMediaPermissionCheckProxy.cpp: Added.
+        (WebKit::UserMediaPermissionCheckProxy::UserMediaPermissionCheckProxy):
+        (WebKit::UserMediaPermissionCheckProxy::setHasPermission):
+        (WebKit::UserMediaPermissionCheckProxy::invalidate):
+        * UIProcess/UserMediaPermissionCheckProxy.h: Added.
+        (WebKit::UserMediaPermissionCheckProxy::create):
+        * UIProcess/UserMediaPermissionRequestManagerProxy.cpp:
+        (WebKit::UserMediaPermissionRequestManagerProxy::invalidateRequests):
+        (WebKit::UserMediaPermissionRequestManagerProxy::createRequest):
+        (WebKit::UserMediaPermissionRequestManagerProxy::didReceiveUserMediaPermissionDecision):
+        (WebKit::UserMediaPermissionRequestManagerProxy::createUserMediaPermissionCheck):
+        (WebKit::UserMediaPermissionRequestManagerProxy::didCompleteUserMediaPermissionCheck):
+        * UIProcess/UserMediaPermissionRequestManagerProxy.h:
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::requestUserMediaPermissionForFrame):
+        (WebKit::WebPageProxy::checkUserMediaPermissionForFrame):
+        (WebKit::WebPageProxy::requestNotificationPermission):
+        * UIProcess/WebPageProxy.h:
+        * UIProcess/WebPageProxy.messages.in:
+
+        * WebKit2.xcodeproj/project.pbxproj: Add UserMediaPermissionCheckProxy.*, and WKUserMediaPermissionCheck.*.
+
+        * WebProcess/MediaStream/UserMediaPermissionRequestManager.cpp:
+        (WebKit::UserMediaPermissionRequestManager::startUserMediaRequest): Renamed from startRequest.
+        (WebKit::UserMediaPermissionRequestManager::cancelUserMediaRequest): Renamed from cancelRequest.
+        (WebKit::UserMediaPermissionRequestManager::didReceiveUserMediaPermissionDecision): m_requestToIDMap -&gt;
+          m_userMediaRequestToIDMap.remove.
+        (WebKit::UserMediaPermissionRequestManager::startUserMediaPermissionCheck): New, start the request.
+        (WebKit::UserMediaPermissionRequestManager::cancelUserMediaPermissionCheck): New, cancel
+          the request.
+        (WebKit::UserMediaPermissionRequestManager::didCompleteUserMediaPermissionCheck): New, 
+          all the request completion method.
+        (WebKit::UserMediaPermissionRequestManager::startRequest): Deleted.
+        (WebKit::UserMediaPermissionRequestManager::cancelRequest): Deleted.
+        * WebProcess/MediaStream/UserMediaPermissionRequestManager.h:
+
+        * WebProcess/WebCoreSupport/WebUserMediaClient.cpp:
+        (WebKit::WebUserMediaClient::requestUserMediaAccess): startRequest -&gt; startUserMediaRequest.
+        (WebKit::WebUserMediaClient::cancelUserMediaAccessRequest): cancelRequest -&gt; cancelUserMediaRequest.
+        (WebKit::WebUserMediaClient::checkUserMediaPermission): New.
+        (WebKit::WebUserMediaClient::cancelUserMediaPermissionCheck): New.
+        * WebProcess/WebCoreSupport/WebUserMediaClient.h:
+
+        * WebProcess/WebPage/WebPage.cpp:
+        (WebKit::WebPage::didCompleteUserMediaPermissionCheck): New.
+        * WebProcess/WebPage/WebPage.h:
+        * WebProcess/WebPage/WebPage.messages.in: Add DidCompleteUserMediaPermissionCheck.
+
</ins><span class="cx"> 2015-12-10  Joseph Pecoraro  &lt;pecoraro@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Remote Inspector: Verify the identity of the other side of XPC connections
</span></span></pre></div>
<a id="trunkSourceWebKit2SharedAPIAPIObjecth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/Shared/API/APIObject.h (193943 => 193944)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/Shared/API/APIObject.h        2015-12-11 04:03:28 UTC (rev 193943)
+++ trunk/Source/WebKit2/Shared/API/APIObject.h        2015-12-11 04:06:05 UTC (rev 193944)
</span><span class="lines">@@ -146,6 +146,7 @@
</span><span class="cx">         UserContentController,
</span><span class="cx">         UserContentExtension,
</span><span class="cx">         UserContentExtensionStore,
</span><ins>+        UserMediaPermissionCheck,
</ins><span class="cx">         UserMediaPermissionRequest,
</span><span class="cx">         Vibration,
</span><span class="cx">         ViewportAttributes,
</span></span></pre></div>
<a id="trunkSourceWebKit2SharedAPIcWKBaseh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/Shared/API/c/WKBase.h (193943 => 193944)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/Shared/API/c/WKBase.h        2015-12-11 04:03:28 UTC (rev 193943)
+++ trunk/Source/WebKit2/Shared/API/c/WKBase.h        2015-12-11 04:06:05 UTC (rev 193944)
</span><span class="lines">@@ -139,6 +139,7 @@
</span><span class="cx"> typedef const struct OpaqueWKUserContentController* WKUserContentControllerRef;
</span><span class="cx"> typedef const struct OpaqueWKUserContentExtensionStore* WKUserContentExtensionStoreRef;
</span><span class="cx"> typedef const struct OpaqueWKUserContentFilter* WKUserContentFilterRef;
</span><ins>+typedef const struct OpaqueWKUserMediaPermissionCheck* WKUserMediaPermissionCheckRef;
</ins><span class="cx"> typedef const struct OpaqueWKUserMediaPermissionRequest* WKUserMediaPermissionRequestRef;
</span><span class="cx"> typedef const struct OpaqueWKUserScript* WKUserScriptRef;
</span><span class="cx"> typedef const struct OpaqueWKVibration* WKVibrationRef;
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessAPIAPIUIClienth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/API/APIUIClient.h (193943 => 193944)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/API/APIUIClient.h        2015-12-11 04:03:28 UTC (rev 193943)
+++ trunk/Source/WebKit2/UIProcess/API/APIUIClient.h        2015-12-11 04:06:05 UTC (rev 193944)
</span><span class="lines">@@ -50,6 +50,7 @@
</span><span class="cx"> class NativeWebKeyboardEvent;
</span><span class="cx"> class NativeWebWheelEvent;
</span><span class="cx"> class NotificationPermissionRequest;
</span><ins>+class UserMediaPermissionCheckProxy;
</ins><span class="cx"> class UserMediaPermissionRequestProxy;
</span><span class="cx"> class WebColorPickerResultListenerProxy;
</span><span class="cx"> class WebFrameProxy;
</span><span class="lines">@@ -131,6 +132,7 @@
</span><span class="cx">     virtual bool runOpenPanel(WebKit::WebPageProxy*, WebKit::WebFrameProxy*, WebKit::WebOpenPanelParameters*, WebKit::WebOpenPanelResultListenerProxy*) { return false; }
</span><span class="cx">     virtual bool decidePolicyForGeolocationPermissionRequest(WebKit::WebPageProxy*, WebKit::WebFrameProxy*, SecurityOrigin*, WebKit::GeolocationPermissionRequestProxy*) { return false; }
</span><span class="cx">     virtual bool decidePolicyForUserMediaPermissionRequest(WebKit::WebPageProxy&amp;, WebKit::WebFrameProxy&amp;, SecurityOrigin&amp;, WebKit::UserMediaPermissionRequestProxy&amp;) { return false; }
</span><ins>+    virtual bool checkUserMediaPermissionForOrigin(WebKit::WebPageProxy&amp;, WebKit::WebFrameProxy&amp;, SecurityOrigin&amp;, WebKit::UserMediaPermissionCheckProxy&amp;) { return false; }
</ins><span class="cx">     virtual bool decidePolicyForNotificationPermissionRequest(WebKit::WebPageProxy*, SecurityOrigin*, WebKit::NotificationPermissionRequest*) { return false; }
</span><span class="cx"> 
</span><span class="cx">     // Printing.
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessAPICWKAPICasth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/API/C/WKAPICast.h (193943 => 193944)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/API/C/WKAPICast.h        2015-12-11 04:03:28 UTC (rev 193943)
+++ trunk/Source/WebKit2/UIProcess/API/C/WKAPICast.h        2015-12-11 04:06:05 UTC (rev 193944)
</span><span class="lines">@@ -74,6 +74,7 @@
</span><span class="cx"> class DownloadProxy;
</span><span class="cx"> class GeolocationPermissionRequestProxy;
</span><span class="cx"> class NotificationPermissionRequest;
</span><ins>+class UserMediaPermissionCheckProxy;
</ins><span class="cx"> class UserMediaPermissionRequestProxy;
</span><span class="cx"> class WebBackForwardList;
</span><span class="cx"> class WebBackForwardListItem;
</span><span class="lines">@@ -161,6 +162,7 @@
</span><span class="cx"> WK_ADD_API_MAPPING(WKUserContentControllerRef, WebUserContentControllerProxy)
</span><span class="cx"> WK_ADD_API_MAPPING(WKUserContentExtensionStoreRef, API::UserContentExtensionStore)
</span><span class="cx"> WK_ADD_API_MAPPING(WKUserContentFilterRef, API::UserContentExtension)
</span><ins>+WK_ADD_API_MAPPING(WKUserMediaPermissionCheckRef, UserMediaPermissionCheckProxy)
</ins><span class="cx"> WK_ADD_API_MAPPING(WKUserMediaPermissionRequestRef, UserMediaPermissionRequestProxy)
</span><span class="cx"> WK_ADD_API_MAPPING(WKUserScriptRef, API::UserScript)
</span><span class="cx"> WK_ADD_API_MAPPING(WKVibrationRef, WebVibrationProxy)
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessAPICWKPagecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/API/C/WKPage.cpp (193943 => 193944)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/API/C/WKPage.cpp        2015-12-11 04:03:28 UTC (rev 193943)
+++ trunk/Source/WebKit2/UIProcess/API/C/WKPage.cpp        2015-12-11 04:06:05 UTC (rev 193944)
</span><span class="lines">@@ -2017,6 +2017,15 @@
</span><span class="cx">             return true;
</span><span class="cx">         }
</span><span class="cx"> 
</span><ins>+        virtual bool checkUserMediaPermissionForOrigin(WebPageProxy&amp; page, WebFrameProxy&amp; frame, API::SecurityOrigin&amp; origin, UserMediaPermissionCheckProxy&amp; request) override
+        {
+            if (!m_client.checkUserMediaPermissionForOrigin)
+                return false;
+
+            m_client.checkUserMediaPermissionForOrigin(toAPI(&amp;page), toAPI(&amp;frame), toAPI(&amp;origin), toAPI(&amp;request), m_client.base.clientInfo);
+            return true;
+        }
+        
</ins><span class="cx">         virtual bool decidePolicyForNotificationPermissionRequest(WebPageProxy* page, API::SecurityOrigin* origin, NotificationPermissionRequest* permissionRequest) override
</span><span class="cx">         {
</span><span class="cx">             if (!m_client.decidePolicyForNotificationPermissionRequest)
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessAPICWKPageUIClienth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/API/C/WKPageUIClient.h (193943 => 193944)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/API/C/WKPageUIClient.h        2015-12-11 04:03:28 UTC (rev 193943)
+++ trunk/Source/WebKit2/UIProcess/API/C/WKPageUIClient.h        2015-12-11 04:06:05 UTC (rev 193944)
</span><span class="lines">@@ -97,6 +97,7 @@
</span><span class="cx"> typedef void (*WKPagePinnedStateDidChangeCallback)(WKPageRef page, const void* clientInfo);
</span><span class="cx"> typedef void (*WKPageIsPlayingAudioDidChangeCallback)(WKPageRef page, const void* clientInfo);
</span><span class="cx"> typedef void (*WKPageDecidePolicyForUserMediaPermissionRequestCallback)(WKPageRef page, WKFrameRef frame, WKSecurityOriginRef origin, WKUserMediaPermissionRequestRef permissionRequest, const void* clientInfo);
</span><ins>+typedef void (*WKCheckUserMediaPermissionCallback)(WKPageRef page, WKFrameRef frame, WKSecurityOriginRef origin, WKUserMediaPermissionCheckRef devicesRequest, const void *clientInfo);
</ins><span class="cx"> typedef void (*WKPageDidClickAutoFillButtonCallback)(WKPageRef page, WKTypeRef userData, const void *clientInfo);
</span><span class="cx"> typedef void (*WKPageMediaSessionMetadataDidChangeCallback)(WKPageRef page, WKMediaSessionMetadataRef metadata, const void* clientInfo);
</span><span class="cx"> 
</span><span class="lines">@@ -545,6 +546,7 @@
</span><span class="cx">     WKPageRunJavaScriptAlertCallback                                    runJavaScriptAlert;
</span><span class="cx">     WKPageRunJavaScriptConfirmCallback                                  runJavaScriptConfirm;
</span><span class="cx">     WKPageRunJavaScriptPromptCallback                                   runJavaScriptPrompt;
</span><ins>+    WKCheckUserMediaPermissionCallback                                  checkUserMediaPermissionForOrigin;
</ins><span class="cx"> } WKPageUIClientV6;
</span><span class="cx"> 
</span><span class="cx"> #ifdef __cplusplus
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessAPICWKUserMediaPermissionCheckcpp"></a>
<div class="addfile"><h4>Added: trunk/Source/WebKit2/UIProcess/API/C/WKUserMediaPermissionCheck.cpp (0 => 193944)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/API/C/WKUserMediaPermissionCheck.cpp                                (rev 0)
+++ trunk/Source/WebKit2/UIProcess/API/C/WKUserMediaPermissionCheck.cpp        2015-12-11 04:06:05 UTC (rev 193944)
</span><span class="lines">@@ -0,0 +1,47 @@
</span><ins>+/*
+ * Copyright (C) 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
+ * 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. ``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
+ * 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 &quot;config.h&quot;
+#include &quot;WKUserMediaPermissionCheck.h&quot;
+
+#include &quot;UserMediaPermissionCheckProxy.h&quot;
+#include &quot;WKAPICast.h&quot;
+#include &quot;WKArray.h&quot;
+#include &quot;WKMutableArray.h&quot;
+#include &quot;WKString.h&quot;
+
+using namespace WebKit;
+
+WKTypeID WKUserMediaPermissionCheckGetTypeID()
+{
+    return toAPI(UserMediaPermissionCheckProxy::APIType);
+}
+
+void WKUserMediaPermissionCheckSetHasPersistentPermission(WKUserMediaPermissionCheckRef userMediaPermissionRequestRef, bool allowed)
+{
+    toImpl(userMediaPermissionRequestRef)-&gt;setHasPersistentPermission(allowed);
+}
+
</ins></span></pre></div>
<a id="trunkSourceWebKit2UIProcessAPICWKUserMediaPermissionCheckh"></a>
<div class="addfile"><h4>Added: trunk/Source/WebKit2/UIProcess/API/C/WKUserMediaPermissionCheck.h (0 => 193944)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/API/C/WKUserMediaPermissionCheck.h                                (rev 0)
+++ trunk/Source/WebKit2/UIProcess/API/C/WKUserMediaPermissionCheck.h        2015-12-11 04:06:05 UTC (rev 193944)
</span><span class="lines">@@ -0,0 +1,44 @@
</span><ins>+/*
+ * Copyright (C) 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
+ * 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. ``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
+ * 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 WKUserMediaPermissionCheck_h
+#define WKUserMediaPermissionCheck_h
+
+#include &lt;WebKit/WKBase.h&gt;
+
+#ifdef __cplusplus
+extern &quot;C&quot; {
+#endif
+
+WK_EXPORT WKTypeID WKUserMediaPermissionCheckGetTypeID();
+
+WK_EXPORT void WKUserMediaPermissionCheckSetHasPersistentPermission(WKUserMediaPermissionCheckRef, bool);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* WKMediaDevicesRequest_h */
</ins></span></pre></div>
<a id="trunkSourceWebKit2UIProcessUserMediaPermissionCheckProxycpp"></a>
<div class="addfile"><h4>Added: trunk/Source/WebKit2/UIProcess/UserMediaPermissionCheckProxy.cpp (0 => 193944)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/UserMediaPermissionCheckProxy.cpp                                (rev 0)
+++ trunk/Source/WebKit2/UIProcess/UserMediaPermissionCheckProxy.cpp        2015-12-11 04:06:05 UTC (rev 193944)
</span><span class="lines">@@ -0,0 +1,55 @@
</span><ins>+/*
+ * Copyright (C) 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
+ * 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. ``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
+ * 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 &quot;config.h&quot;
+#include &quot;UserMediaPermissionCheckProxy.h&quot;
+
+#include &quot;UserMediaPermissionRequestManagerProxy.h&quot;
+
+namespace WebKit {
+
+UserMediaPermissionCheckProxy::UserMediaPermissionCheckProxy(UserMediaPermissionRequestManagerProxy&amp; manager, uint64_t userMediaID)
+    : m_manager(&amp;manager)
+    , m_userMediaID(userMediaID)
+{
+}
+
+void UserMediaPermissionCheckProxy::setHasPersistentPermission(bool allowed)
+{
+    ASSERT(m_manager);
+    if (!m_manager)
+        return;
+
+    m_manager-&gt;didCompleteUserMediaPermissionCheck(m_userMediaID, allowed);
+    m_manager = nullptr;
+}
+
+void UserMediaPermissionCheckProxy::invalidate()
+{
+    m_manager = nullptr;
+}
+
+} // namespace WebKit
+
</ins></span></pre></div>
<a id="trunkSourceWebKit2UIProcessUserMediaPermissionCheckProxyh"></a>
<div class="addfile"><h4>Added: trunk/Source/WebKit2/UIProcess/UserMediaPermissionCheckProxy.h (0 => 193944)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/UserMediaPermissionCheckProxy.h                                (rev 0)
+++ trunk/Source/WebKit2/UIProcess/UserMediaPermissionCheckProxy.h        2015-12-11 04:06:05 UTC (rev 193944)
</span><span class="lines">@@ -0,0 +1,57 @@
</span><ins>+/*
+ * Copyright (C) 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
+ * 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. ``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
+ * 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 UserMediaPermissionCheckProxy_h
+#define UserMediaPermissionCheckProxy_h
+
+#include &quot;APIObject.h&quot;
+#include &lt;WebCore/RealtimeMediaSource.h&gt;
+#include &lt;wtf/Vector.h&gt;
+#include &lt;wtf/text/WTFString.h&gt;
+
+namespace WebKit {
+
+class UserMediaPermissionRequestManagerProxy;
+
+class UserMediaPermissionCheckProxy : public API::ObjectImpl&lt;API::Object::Type::UserMediaPermissionCheck&gt; {
+public:
+    static Ref&lt;UserMediaPermissionCheckProxy&gt; create(UserMediaPermissionRequestManagerProxy&amp; manager, uint64_t userMediaID)
+    {
+        return adoptRef(*new UserMediaPermissionCheckProxy(manager, userMediaID));
+    }
+
+    void setHasPersistentPermission(bool allowed);
+    void invalidate();
+
+private:
+    UserMediaPermissionCheckProxy(UserMediaPermissionRequestManagerProxy&amp;, uint64_t userMediaID);
+
+    UserMediaPermissionRequestManagerProxy* m_manager;
+    uint64_t m_userMediaID;
+};
+
+} // namespace WebKit
+
+#endif // UserMediaPermissionCheckProxy_h
</ins></span></pre></div>
<a id="trunkSourceWebKit2UIProcessUserMediaPermissionRequestManagerProxycpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/UserMediaPermissionRequestManagerProxy.cpp (193943 => 193944)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/UserMediaPermissionRequestManagerProxy.cpp        2015-12-11 04:03:28 UTC (rev 193943)
+++ trunk/Source/WebKit2/UIProcess/UserMediaPermissionRequestManagerProxy.cpp        2015-12-11 04:06:05 UTC (rev 193944)
</span><span class="lines">@@ -32,17 +32,17 @@
</span><span class="cx"> 
</span><span class="cx"> void UserMediaPermissionRequestManagerProxy::invalidateRequests()
</span><span class="cx"> {
</span><del>-    for (auto&amp; request : m_pendingRequests.values())
</del><ins>+    for (auto&amp; request : m_pendingUserMediaRequests.values())
</ins><span class="cx">         request-&gt;invalidate();
</span><span class="cx"> 
</span><del>-    m_pendingRequests.clear();
</del><ins>+    m_pendingUserMediaRequests.clear();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-PassRefPtr&lt;UserMediaPermissionRequestProxy&gt; UserMediaPermissionRequestManagerProxy::createRequest(uint64_t userMediaID, const Vector&lt;String&gt;&amp; audioDeviceUIDs, const Vector&lt;String&gt;&amp; videoDeviceUIDs)
</del><ins>+Ref&lt;UserMediaPermissionRequestProxy&gt; UserMediaPermissionRequestManagerProxy::createRequest(uint64_t userMediaID, const Vector&lt;String&gt;&amp; audioDeviceUIDs, const Vector&lt;String&gt;&amp; videoDeviceUIDs)
</ins><span class="cx"> {
</span><del>-    RefPtr&lt;UserMediaPermissionRequestProxy&gt; request = UserMediaPermissionRequestProxy::create(*this, userMediaID, audioDeviceUIDs, videoDeviceUIDs);
-    m_pendingRequests.add(userMediaID, request.get());
-    return request.release();
</del><ins>+    Ref&lt;UserMediaPermissionRequestProxy&gt; request = UserMediaPermissionRequestProxy::create(*this, userMediaID, audioDeviceUIDs, videoDeviceUIDs);
+    m_pendingUserMediaRequests.add(userMediaID, request.ptr());
+    return request;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void UserMediaPermissionRequestManagerProxy::didReceiveUserMediaPermissionDecision(uint64_t userMediaID, bool allowed, const String&amp; audioDeviceUID, const String&amp; videoDeviceUID)
</span><span class="lines">@@ -50,7 +50,7 @@
</span><span class="cx">     if (!m_page.isValid())
</span><span class="cx">         return;
</span><span class="cx"> 
</span><del>-    if (!m_pendingRequests.take(userMediaID))
</del><ins>+    if (!m_pendingUserMediaRequests.take(userMediaID))
</ins><span class="cx">         return;
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(MEDIA_STREAM)
</span><span class="lines">@@ -60,4 +60,26 @@
</span><span class="cx"> #endif
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+Ref&lt;UserMediaPermissionCheckProxy&gt; UserMediaPermissionRequestManagerProxy::createUserMediaPermissionCheck(uint64_t userMediaID)
+{
+    Ref&lt;UserMediaPermissionCheckProxy&gt; request = UserMediaPermissionCheckProxy::create(*this, userMediaID);
+    m_pendingDeviceRequests.add(userMediaID, request.ptr());
+    return request;
+}
+
+void UserMediaPermissionRequestManagerProxy::didCompleteUserMediaPermissionCheck(uint64_t userMediaID, bool allowed)
+{
+    if (!m_page.isValid())
+        return;
+
+    if (!m_pendingDeviceRequests.take(userMediaID))
+        return;
+
+#if ENABLE(MEDIA_STREAM)
+    m_page.process().send(Messages::WebPage::DidCompleteUserMediaPermissionCheck(userMediaID, allowed), m_page.pageID());
+#else
+    UNUSED_PARAM(allowed);
+#endif
+}
+
</ins><span class="cx"> } // namespace WebKit
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessUserMediaPermissionRequestManagerProxyh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/UserMediaPermissionRequestManagerProxy.h (193943 => 193944)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/UserMediaPermissionRequestManagerProxy.h        2015-12-11 04:03:28 UTC (rev 193943)
+++ trunk/Source/WebKit2/UIProcess/UserMediaPermissionRequestManagerProxy.h        2015-12-11 04:06:05 UTC (rev 193944)
</span><span class="lines">@@ -19,6 +19,7 @@
</span><span class="cx"> #ifndef UserMediaPermissionRequestManagerProxy_h
</span><span class="cx"> #define UserMediaPermissionRequestManagerProxy_h
</span><span class="cx"> 
</span><ins>+#include &quot;UserMediaPermissionCheckProxy.h&quot;
</ins><span class="cx"> #include &quot;UserMediaPermissionRequestProxy.h&quot;
</span><span class="cx"> #include &lt;wtf/HashMap.h&gt;
</span><span class="cx"> 
</span><span class="lines">@@ -32,14 +33,16 @@
</span><span class="cx"> 
</span><span class="cx">     void invalidateRequests();
</span><span class="cx"> 
</span><del>-    // Create a request to be presented to the user.
-    PassRefPtr&lt;UserMediaPermissionRequestProxy&gt; createRequest(uint64_t userMediaID, const Vector&lt;String&gt;&amp; audioDeviceUIDs, const Vector&lt;String&gt;&amp; videoDeviceUIDs);
-
-    // Called by UserMediaPermissionRequestProxy when a decision is made by the user.
</del><ins>+    Ref&lt;UserMediaPermissionRequestProxy&gt; createRequest(uint64_t userMediaID, const Vector&lt;String&gt;&amp; audioDeviceUIDs, const Vector&lt;String&gt;&amp; videoDeviceUIDs);
</ins><span class="cx">     void didReceiveUserMediaPermissionDecision(uint64_t, bool allow, const String&amp; audioDeviceUID, const String&amp; videoDeviceUID);
</span><span class="cx"> 
</span><ins>+
+    Ref&lt;UserMediaPermissionCheckProxy&gt; createUserMediaPermissionCheck(uint64_t userMediaID);
+    void didCompleteUserMediaPermissionCheck(uint64_t, bool allow);
+
</ins><span class="cx"> private:
</span><del>-    HashMap&lt;uint64_t, RefPtr&lt;UserMediaPermissionRequestProxy&gt;&gt; m_pendingRequests;
</del><ins>+    HashMap&lt;uint64_t, RefPtr&lt;UserMediaPermissionRequestProxy&gt;&gt; m_pendingUserMediaRequests;
+    HashMap&lt;uint64_t, RefPtr&lt;UserMediaPermissionCheckProxy&gt;&gt; m_pendingDeviceRequests;
</ins><span class="cx">     WebPageProxy&amp; m_page;
</span><span class="cx"> };
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessUserMediaPermissionRequestProxyh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/UserMediaPermissionRequestProxy.h (193943 => 193944)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/UserMediaPermissionRequestProxy.h        2015-12-11 04:03:28 UTC (rev 193943)
+++ trunk/Source/WebKit2/UIProcess/UserMediaPermissionRequestProxy.h        2015-12-11 04:06:05 UTC (rev 193944)
</span><span class="lines">@@ -21,7 +21,6 @@
</span><span class="cx"> 
</span><span class="cx"> #include &quot;APIObject.h&quot;
</span><span class="cx"> #include &lt;WebCore/RealtimeMediaSource.h&gt;
</span><del>-#include &lt;wtf/PassRefPtr.h&gt;
</del><span class="cx"> #include &lt;wtf/Vector.h&gt;
</span><span class="cx"> #include &lt;wtf/text/WTFString.h&gt;
</span><span class="cx"> 
</span><span class="lines">@@ -31,9 +30,9 @@
</span><span class="cx"> 
</span><span class="cx"> class UserMediaPermissionRequestProxy : public API::ObjectImpl&lt;API::Object::Type::UserMediaPermissionRequest&gt; {
</span><span class="cx"> public:
</span><del>-    static PassRefPtr&lt;UserMediaPermissionRequestProxy&gt; create(UserMediaPermissionRequestManagerProxy&amp; manager, uint64_t userMediaID, const Vector&lt;String&gt;&amp; videoDeviceUIDs, const Vector&lt;String&gt;&amp; audioDeviceUIDs)
</del><ins>+    static Ref&lt;UserMediaPermissionRequestProxy&gt; create(UserMediaPermissionRequestManagerProxy&amp; manager, uint64_t userMediaID, const Vector&lt;String&gt;&amp; videoDeviceUIDs, const Vector&lt;String&gt;&amp; audioDeviceUIDs)
</ins><span class="cx">     {
</span><del>-        return adoptRef(new UserMediaPermissionRequestProxy(manager, userMediaID, videoDeviceUIDs, audioDeviceUIDs));
</del><ins>+        return adoptRef(*new UserMediaPermissionRequestProxy(manager, userMediaID, videoDeviceUIDs, audioDeviceUIDs));
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     void allow(const String&amp; videoDeviceUID, const String&amp; audioDeviceUID);
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessWebPageProxycpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp (193943 => 193944)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp        2015-12-11 04:03:28 UTC (rev 193943)
+++ trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp        2015-12-11 04:06:05 UTC (rev 193944)
</span><span class="lines">@@ -5261,6 +5261,18 @@
</span><span class="cx">         request-&gt;deny();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void WebPageProxy::checkUserMediaPermissionForFrame(uint64_t userMediaID, uint64_t frameID, String originIdentifier)
+{
+    WebFrameProxy* frame = m_process-&gt;webFrame(frameID);
+    MESSAGE_CHECK(frame);
+
+    RefPtr&lt;API::SecurityOrigin&gt; origin = API::SecurityOrigin::create(SecurityOrigin::createFromDatabaseIdentifier(originIdentifier));
+    RefPtr&lt;UserMediaPermissionCheckProxy&gt; request = m_userMediaPermissionRequestManager.createUserMediaPermissionCheck(userMediaID);
+
+    if (!m_uiClient-&gt;checkUserMediaPermissionForOrigin(*this, *frame, *origin.get(), *request.get()))
+        request-&gt;setHasPersistentPermission(false);
+}
+
</ins><span class="cx"> void WebPageProxy::requestNotificationPermission(uint64_t requestID, const String&amp; originString)
</span><span class="cx"> {
</span><span class="cx">     if (!isRequestIDValid(requestID))
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessWebPageProxyh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/WebPageProxy.h (193943 => 193944)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/WebPageProxy.h        2015-12-11 04:03:28 UTC (rev 193943)
+++ trunk/Source/WebKit2/UIProcess/WebPageProxy.h        2015-12-11 04:06:05 UTC (rev 193944)
</span><span class="lines">@@ -1190,6 +1190,7 @@
</span><span class="cx">     void requestGeolocationPermissionForFrame(uint64_t geolocationID, uint64_t frameID, String originIdentifier);
</span><span class="cx"> 
</span><span class="cx">     void requestUserMediaPermissionForFrame(uint64_t userMediaID, uint64_t frameID, String originIdentifier, const Vector&lt;String&gt;&amp; audioDeviceUIDs, const Vector&lt;String&gt;&amp; videoDeviceUIDs);
</span><ins>+    void checkUserMediaPermissionForFrame(uint64_t userMediaID, uint64_t frameID, String originIdentifier);
</ins><span class="cx"> 
</span><span class="cx">     void runModal();
</span><span class="cx">     void notifyScrollerThumbIsVisibleInRect(const WebCore::IntRect&amp;);
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessWebPageProxymessagesin"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/WebPageProxy.messages.in (193943 => 193944)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/WebPageProxy.messages.in        2015-12-11 04:03:28 UTC (rev 193943)
+++ trunk/Source/WebKit2/UIProcess/WebPageProxy.messages.in        2015-12-11 04:06:05 UTC (rev 193944)
</span><span class="lines">@@ -262,6 +262,7 @@
</span><span class="cx"> #if ENABLE(MEDIA_STREAM)
</span><span class="cx">     # MediaSteam messages
</span><span class="cx">     RequestUserMediaPermissionForFrame(uint64_t userMediaID, uint64_t frameID, String originIdentifier, Vector&lt;String&gt; audioDeviceUIDs, Vector&lt;String&gt; videoDeviceUIDs)
</span><ins>+    CheckUserMediaPermissionForFrame(uint64_t userMediaID, uint64_t frameID, String originIdentifier)
</ins><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx">     # Notification messages
</span></span></pre></div>
<a id="trunkSourceWebKit2WebKit2xcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebKit2.xcodeproj/project.pbxproj (193943 => 193944)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebKit2.xcodeproj/project.pbxproj        2015-12-11 04:03:28 UTC (rev 193943)
+++ trunk/Source/WebKit2/WebKit2.xcodeproj/project.pbxproj        2015-12-11 04:06:05 UTC (rev 193944)
</span><span class="lines">@@ -64,6 +64,10 @@
</span><span class="cx">                 00B9661618E24CBA00CE1F88 /* APIFindClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B9661518E24CBA00CE1F88 /* APIFindClient.h */; };
</span><span class="cx">                 00B9661918E25AE100CE1F88 /* FindClient.mm in Sources */ = {isa = PBXBuildFile; fileRef = 00B9661718E25AE100CE1F88 /* FindClient.mm */; };
</span><span class="cx">                 00B9661A18E25AE100CE1F88 /* FindClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B9661818E25AE100CE1F88 /* FindClient.h */; };
</span><ins>+                07297F9E1C17BBEA003F0735 /* UserMediaPermissionCheckProxy.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 07297F9C1C17BBEA003F0735 /* UserMediaPermissionCheckProxy.cpp */; settings = {ASSET_TAGS = (); }; };
+                07297F9F1C17BBEA003F0735 /* UserMediaPermissionCheckProxy.h in Headers */ = {isa = PBXBuildFile; fileRef = 07297F9D1C17BBEA003F0735 /* UserMediaPermissionCheckProxy.h */; settings = {ASSET_TAGS = (); }; };
+                07297FA21C186ADB003F0735 /* WKUserMediaPermissionCheck.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 07297FA01C186ADB003F0735 /* WKUserMediaPermissionCheck.cpp */; settings = {ASSET_TAGS = (); }; };
+                07297FA31C186ADB003F0735 /* WKUserMediaPermissionCheck.h in Headers */ = {isa = PBXBuildFile; fileRef = 07297FA11C186ADB003F0735 /* WKUserMediaPermissionCheck.h */; settings = {ATTRIBUTES = (Private, ); }; };
</ins><span class="cx">                 076E884E1A13CADF005E90FC /* APIContextMenuClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 076E884D1A13CADF005E90FC /* APIContextMenuClient.h */; };
</span><span class="cx">                 0F0C365818C051BA00F607D7 /* RemoteLayerTreeHostIOS.mm in Sources */ = {isa = PBXBuildFile; fileRef = 0F0C365718C051BA00F607D7 /* RemoteLayerTreeHostIOS.mm */; };
</span><span class="cx">                 0F0C365A18C0555800F607D7 /* LayerRepresentation.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F0C365918C0555800F607D7 /* LayerRepresentation.h */; };
</span><span class="lines">@@ -2167,6 +2171,10 @@
</span><span class="cx">                 00B9661518E24CBA00CE1F88 /* APIFindClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = APIFindClient.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 00B9661718E25AE100CE1F88 /* FindClient.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = FindClient.mm; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 00B9661818E25AE100CE1F88 /* FindClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FindClient.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                07297F9C1C17BBEA003F0735 /* UserMediaPermissionCheckProxy.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = UserMediaPermissionCheckProxy.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                07297F9D1C17BBEA003F0735 /* UserMediaPermissionCheckProxy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UserMediaPermissionCheckProxy.h; sourceTree = &quot;&lt;group&gt;&quot;; };
+                07297FA01C186ADB003F0735 /* WKUserMediaPermissionCheck.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WKUserMediaPermissionCheck.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                07297FA11C186ADB003F0735 /* WKUserMediaPermissionCheck.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKUserMediaPermissionCheck.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 076E884D1A13CADF005E90FC /* APIContextMenuClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = APIContextMenuClient.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 076E884F1A13CBC6005E90FC /* APIInjectedBundlePageContextMenuClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = APIInjectedBundlePageContextMenuClient.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0867D6A5FE840307C02AAC07 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = &quot;&lt;absolute&gt;&quot;; };
</span><span class="lines">@@ -6185,6 +6193,8 @@
</span><span class="cx">                                 BC06F43912DBCCFB002D78DE /* GeolocationPermissionRequestProxy.cpp */,
</span><span class="cx">                                 BC06F43812DBCCFB002D78DE /* GeolocationPermissionRequestProxy.h */,
</span><span class="cx">                                 31607F3819627002009B87DA /* LegacySessionStateCoding.h */,
</span><ins>+                                07297F9C1C17BBEA003F0735 /* UserMediaPermissionCheckProxy.cpp */,
+                                07297F9D1C17BBEA003F0735 /* UserMediaPermissionCheckProxy.h */,
</ins><span class="cx">                                 BC6EDAA5111271C600E7678B /* PageClient.h */,
</span><span class="cx">                                 1AC75379183A9FDA0072CB15 /* PageLoadState.cpp */,
</span><span class="cx">                                 1AC7537A183A9FDB0072CB15 /* PageLoadState.h */,
</span><span class="lines">@@ -6481,6 +6491,8 @@
</span><span class="cx">                                 7C89D29E1A678554003A5FDE /* WKUserContentControllerRef.h */,
</span><span class="cx">                                 7C2413061AACFCB400A58C15 /* WKUserContentExtensionStoreRef.cpp */,
</span><span class="cx">                                 7C2413071AACFCB400A58C15 /* WKUserContentExtensionStoreRef.h */,
</span><ins>+                                07297FA01C186ADB003F0735 /* WKUserMediaPermissionCheck.cpp */,
+                                07297FA11C186ADB003F0735 /* WKUserMediaPermissionCheck.h */,
</ins><span class="cx">                                 4A410F3519AF7AC3002EBAB5 /* WKUserMediaPermissionRequest.cpp */,
</span><span class="cx">                                 4A410F3619AF7AC3002EBAB5 /* WKUserMediaPermissionRequest.h */,
</span><span class="cx">                                 7C89D2A11A678875003A5FDE /* WKUserScriptRef.cpp */,
</span><span class="lines">@@ -7774,6 +7786,7 @@
</span><span class="cx">                                 BC06F43A12DBCCFB002D78DE /* GeolocationPermissionRequestProxy.h in Headers */,
</span><span class="cx">                                 2DA944A41884E4F000ED86DB /* GestureTypes.h in Headers */,
</span><span class="cx">                                 2DA049B8180CCD0A00AAFA9E /* GraphicsLayerCARemote.h in Headers */,
</span><ins>+                                07297FA31C186ADB003F0735 /* WKUserMediaPermissionCheck.h in Headers */,
</ins><span class="cx">                                 C0CE72AD1247E78D00BC0EC4 /* HandleMessage.h in Headers */,
</span><span class="cx">                                 1AC75A1B1B3368270056745B /* HangDetectionDisabler.h in Headers */,
</span><span class="cx">                                 37F90DE31376560E0051CF68 /* HTTPCookieAcceptPolicy.h in Headers */,
</span><span class="lines">@@ -8266,6 +8279,7 @@
</span><span class="cx">                                 1A445B9F184D5FB5004B3414 /* WKContextInjectedBundleClient.h in Headers */,
</span><span class="cx">                                 51A555F6128C6C47009ABCEC /* WKContextMenuItem.h in Headers */,
</span><span class="cx">                                 51A55601128C6D92009ABCEC /* WKContextMenuItemTypes.h in Headers */,
</span><ins>+                                07297F9F1C17BBEA003F0735 /* UserMediaPermissionCheckProxy.h in Headers */,
</ins><span class="cx">                                 BCC938E11180DE440085E5FE /* WKContextPrivate.h in Headers */,
</span><span class="cx">                                 9FB5F395169E6A80002C25BF /* WKContextPrivateMac.h in Headers */,
</span><span class="cx">                                 3309345B1315B9980097A7BC /* WKCookieManager.h in Headers */,
</span><span class="lines">@@ -10084,6 +10098,7 @@
</span><span class="cx">                                 BC54CC1312D674EE005C67B0 /* WKGeolocationManager.cpp in Sources */,
</span><span class="cx">                                 BC06F44F12DBDF3F002D78DE /* WKGeolocationPermissionRequest.cpp in Sources */,
</span><span class="cx">                                 BC0E619912D6CD120012A72A /* WKGeolocationPosition.cpp in Sources */,
</span><ins>+                                07297FA21C186ADB003F0735 /* WKUserMediaPermissionCheck.cpp in Sources */,
</ins><span class="cx">                                 0FCB4E5018BBE044000FCFC9 /* WKGeolocationProviderIOS.mm in Sources */,
</span><span class="cx">                                 0FCB4E5118BBE044000FCFC9 /* WKGeolocationProviderIOSObjCSecurityOrigin.mm in Sources */,
</span><span class="cx">                                 0F174AA7142AAC610039250F /* WKGeometry.cpp in Sources */,
</span><span class="lines">@@ -10098,6 +10113,7 @@
</span><span class="cx">                                 0F3C725C196F605200AEDD0C /* WKInspectorHighlightView.mm in Sources */,
</span><span class="cx">                                 A54293A5195A43DD002782C7 /* WKInspectorNodeSearchGestureRecognizer.mm in Sources */,
</span><span class="cx">                                 51A9E10A1315CD18009E7031 /* WKKeyValueStorageManager.cpp in Sources */,
</span><ins>+                                07297F9E1C17BBEA003F0735 /* UserMediaPermissionCheckProxy.cpp in Sources */,
</ins><span class="cx">                                 33D3A3B51339600B00709BE4 /* WKMediaCacheManager.cpp in Sources */,
</span><span class="cx">                                 C98C48A91B6FD5B500145103 /* WKMediaSessionFocusManager.cpp in Sources */,
</span><span class="cx">                                 C9CD439E1B4B025300239E33 /* WKMediaSessionMetadata.cpp in Sources */,
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessMediaStreamUserMediaPermissionRequestManagercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/MediaStream/UserMediaPermissionRequestManager.cpp (193943 => 193944)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/MediaStream/UserMediaPermissionRequestManager.cpp        2015-12-11 04:03:28 UTC (rev 193943)
+++ trunk/Source/WebKit2/WebProcess/MediaStream/UserMediaPermissionRequestManager.cpp        2015-12-11 04:06:05 UTC (rev 193944)
</span><span class="lines">@@ -45,7 +45,7 @@
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void UserMediaPermissionRequestManager::startRequest(UserMediaRequest&amp; request)
</del><ins>+void UserMediaPermissionRequestManager::startUserMediaRequest(UserMediaRequest&amp; request)
</ins><span class="cx"> {
</span><span class="cx">     Document* document = downcast&lt;Document&gt;(request.scriptExecutionContext());
</span><span class="cx">     Frame* frame = document ? document-&gt;frame() : nullptr;
</span><span class="lines">@@ -56,8 +56,8 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     uint64_t requestID = generateRequestID();
</span><del>-    m_idToRequestMap.add(requestID, &amp;request);
-    m_requestToIDMap.add(&amp;request, requestID);
</del><ins>+    m_idToUserMediaRequestMap.add(requestID, &amp;request);
+    m_userMediaRequestToIDMap.add(&amp;request, requestID);
</ins><span class="cx"> 
</span><span class="cx">     WebFrame* webFrame = WebFrame::fromCoreFrame(*frame);
</span><span class="cx">     ASSERT(webFrame);
</span><span class="lines">@@ -66,20 +66,20 @@
</span><span class="cx">     m_page.send(Messages::WebPageProxy::RequestUserMediaPermissionForFrame(requestID, webFrame-&gt;frameID(), origin-&gt;databaseIdentifier(), request.audioDeviceUIDs(), request.videoDeviceUIDs()));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void UserMediaPermissionRequestManager::cancelRequest(UserMediaRequest&amp; request)
</del><ins>+void UserMediaPermissionRequestManager::cancelUserMediaRequest(UserMediaRequest&amp; request)
</ins><span class="cx"> {
</span><del>-    uint64_t requestID = m_requestToIDMap.take(&amp;request);
</del><ins>+    uint64_t requestID = m_userMediaRequestToIDMap.take(&amp;request);
</ins><span class="cx">     if (!requestID)
</span><span class="cx">         return;
</span><del>-    m_idToRequestMap.remove(requestID);
</del><ins>+    m_idToUserMediaRequestMap.remove(requestID);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void UserMediaPermissionRequestManager::didReceiveUserMediaPermissionDecision(uint64_t requestID, bool allowed, const String&amp; audioDeviceUID, const String&amp; videoDeviceUID)
</span><span class="cx"> {
</span><del>-    RefPtr&lt;UserMediaRequest&gt; request = m_idToRequestMap.take(requestID);
</del><ins>+    RefPtr&lt;UserMediaRequest&gt; request = m_idToUserMediaRequestMap.take(requestID);
</ins><span class="cx">     if (!request)
</span><span class="cx">         return;
</span><del>-    m_requestToIDMap.remove(request);
</del><ins>+    m_userMediaRequestToIDMap.remove(request);
</ins><span class="cx"> 
</span><span class="cx">     if (allowed)
</span><span class="cx">         request-&gt;userMediaAccessGranted(audioDeviceUID, videoDeviceUID);
</span><span class="lines">@@ -87,6 +87,45 @@
</span><span class="cx">         request-&gt;userMediaAccessDenied();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void UserMediaPermissionRequestManager::startUserMediaPermissionCheck(WebCore::UserMediaPermissionCheck&amp; request)
+{
+    Document* document = downcast&lt;Document&gt;(request.scriptExecutionContext());
+    Frame* frame = document ? document-&gt;frame() : nullptr;
+
+    if (!frame) {
+        request.setHasPersistentPermission(false);
+        return;
+    }
+
+    uint64_t requestID = generateRequestID();
+    m_idToUserMediaPermissionCheckMap.add(requestID, &amp;request);
+    m_userMediaPermissionCheckToIDMap.add(&amp;request, requestID);
+
+    WebFrame* webFrame = WebFrame::fromCoreFrame(*frame);
+    ASSERT(webFrame);
+
+    SecurityOrigin* origin = request.securityOrigin();
+    m_page.send(Messages::WebPageProxy::CheckUserMediaPermissionForFrame(requestID, webFrame-&gt;frameID(), origin-&gt;databaseIdentifier()));
+}
+
+void UserMediaPermissionRequestManager::cancelUserMediaPermissionCheck(WebCore::UserMediaPermissionCheck&amp; request)
+{
+    uint64_t requestID = m_userMediaPermissionCheckToIDMap.take(&amp;request);
+    if (!requestID)
+        return;
+    m_idToUserMediaPermissionCheckMap.remove(requestID);
+}
+
+void UserMediaPermissionRequestManager::didCompleteUserMediaPermissionCheck(uint64_t requestID, bool allowed)
+{
+    RefPtr&lt;UserMediaPermissionCheck&gt; request = m_idToUserMediaPermissionCheckMap.take(requestID);
+    if (!request)
+        return;
+    m_userMediaPermissionCheckToIDMap.remove(request);
+    
+    request-&gt;setHasPersistentPermission(allowed);
+}
+
</ins><span class="cx"> } // namespace WebKit
</span><span class="cx"> 
</span><span class="cx"> #endif // ENABLE(MEDIA_STREAM)
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessMediaStreamUserMediaPermissionRequestManagerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/MediaStream/UserMediaPermissionRequestManager.h (193943 => 193944)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/MediaStream/UserMediaPermissionRequestManager.h        2015-12-11 04:03:28 UTC (rev 193943)
+++ trunk/Source/WebKit2/WebProcess/MediaStream/UserMediaPermissionRequestManager.h        2015-12-11 04:06:05 UTC (rev 193944)
</span><span class="lines">@@ -21,6 +21,7 @@
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(MEDIA_STREAM)
</span><span class="cx"> 
</span><ins>+#include &lt;WebCore/UserMediaPermissionCheck.h&gt;
</ins><span class="cx"> #include &lt;WebCore/UserMediaRequest.h&gt;
</span><span class="cx"> #include &lt;wtf/HashMap.h&gt;
</span><span class="cx"> #include &lt;wtf/Ref.h&gt;
</span><span class="lines">@@ -34,16 +35,22 @@
</span><span class="cx"> public:
</span><span class="cx">     explicit UserMediaPermissionRequestManager(WebPage&amp;);
</span><span class="cx"> 
</span><del>-    void startRequest(WebCore::UserMediaRequest&amp;);
-    void cancelRequest(WebCore::UserMediaRequest&amp;);
</del><ins>+    void startUserMediaRequest(WebCore::UserMediaRequest&amp;);
+    void cancelUserMediaRequest(WebCore::UserMediaRequest&amp;);
+    void didReceiveUserMediaPermissionDecision(uint64_t requestID, bool allowed, const String&amp; audioDeviceUID, const String&amp; videoDeviceUID);
</ins><span class="cx"> 
</span><del>-    void didReceiveUserMediaPermissionDecision(uint64_t userMediaID, bool allowed, const String&amp; audioDeviceUID, const String&amp; videoDeviceUID);
</del><ins>+    void startUserMediaPermissionCheck(WebCore::UserMediaPermissionCheck&amp;);
+    void cancelUserMediaPermissionCheck(WebCore::UserMediaPermissionCheck&amp;);
+    void didCompleteUserMediaPermissionCheck(uint64_t requestID, bool allowed);
</ins><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     WebPage&amp; m_page;
</span><span class="cx"> 
</span><del>-    HashMap&lt;uint64_t, RefPtr&lt;WebCore::UserMediaRequest&gt;&gt; m_idToRequestMap;
-    HashMap&lt;RefPtr&lt;WebCore::UserMediaRequest&gt;, uint64_t&gt; m_requestToIDMap;
</del><ins>+    HashMap&lt;uint64_t, RefPtr&lt;WebCore::UserMediaRequest&gt;&gt; m_idToUserMediaRequestMap;
+    HashMap&lt;RefPtr&lt;WebCore::UserMediaRequest&gt;, uint64_t&gt; m_userMediaRequestToIDMap;
+
+    HashMap&lt;uint64_t, RefPtr&lt;WebCore::UserMediaPermissionCheck&gt;&gt; m_idToUserMediaPermissionCheckMap;
+    HashMap&lt;RefPtr&lt;WebCore::UserMediaPermissionCheck&gt;, uint64_t&gt; m_userMediaPermissionCheckToIDMap;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace WebKit
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebCoreSupportWebUserMediaClientcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebUserMediaClient.cpp (193943 => 193944)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebUserMediaClient.cpp        2015-12-11 04:03:28 UTC (rev 193943)
+++ trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebUserMediaClient.cpp        2015-12-11 04:06:05 UTC (rev 193944)
</span><span class="lines">@@ -39,17 +39,26 @@
</span><span class="cx">     delete this;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void WebUserMediaClient::requestUserMediaAccess(Ref&lt;UserMediaRequest&gt;&amp;&amp; prRequest)
</del><ins>+void WebUserMediaClient::requestUserMediaAccess(UserMediaRequest&amp; request)
</ins><span class="cx"> {
</span><del>-    UserMediaRequest&amp; request = prRequest.leakRef();
-    m_page.userMediaPermissionRequestManager().startRequest(request);
</del><ins>+    m_page.userMediaPermissionRequestManager().startUserMediaRequest(request);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void WebUserMediaClient::cancelUserMediaAccessRequest(UserMediaRequest&amp; request)
</span><span class="cx"> {
</span><del>-    m_page.userMediaPermissionRequestManager().cancelRequest(request);
</del><ins>+    m_page.userMediaPermissionRequestManager().cancelUserMediaRequest(request);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void WebUserMediaClient::checkUserMediaPermission(WebCore::UserMediaPermissionCheck&amp; request)
+{
+    m_page.userMediaPermissionRequestManager().startUserMediaPermissionCheck(request);
+}
+
+void WebUserMediaClient::cancelUserMediaPermissionCheck(WebCore::UserMediaPermissionCheck&amp; request)
+{
+    m_page.userMediaPermissionRequestManager().cancelUserMediaPermissionCheck(request);
+}
+
</ins><span class="cx"> } // namespace WebKit;
</span><span class="cx"> 
</span><span class="cx"> #endif // MEDIA_STREAM
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebCoreSupportWebUserMediaClienth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebUserMediaClient.h (193943 => 193944)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebUserMediaClient.h        2015-12-11 04:03:28 UTC (rev 193943)
+++ trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebUserMediaClient.h        2015-12-11 04:06:05 UTC (rev 193944)
</span><span class="lines">@@ -33,10 +33,14 @@
</span><span class="cx">     WebUserMediaClient(WebPage&amp;);
</span><span class="cx"> 
</span><span class="cx"> private:
</span><del>-    virtual void pageDestroyed() override;
-    void requestUserMediaAccess(Ref&lt;WebCore::UserMediaRequest&gt;&amp;&amp;) override;
</del><ins>+    void pageDestroyed() override;
+
+    void requestUserMediaAccess(WebCore::UserMediaRequest&amp;) override;
</ins><span class="cx">     void cancelUserMediaAccessRequest(WebCore::UserMediaRequest&amp;) override;
</span><span class="cx"> 
</span><ins>+    void checkUserMediaPermission(WebCore::UserMediaPermissionCheck&amp;) override;
+    void cancelUserMediaPermissionCheck(WebCore::UserMediaPermissionCheck&amp;) override;
+
</ins><span class="cx">     WebPage&amp; m_page;
</span><span class="cx"> };
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebPageWebPagecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/WebPage/WebPage.cpp (193943 => 193944)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebPage/WebPage.cpp        2015-12-11 04:03:28 UTC (rev 193943)
+++ trunk/Source/WebKit2/WebProcess/WebPage/WebPage.cpp        2015-12-11 04:06:05 UTC (rev 193944)
</span><span class="lines">@@ -3365,6 +3365,11 @@
</span><span class="cx"> {
</span><span class="cx">     m_userMediaPermissionRequestManager.didReceiveUserMediaPermissionDecision(userMediaID, allowed, audioDeviceUID, videoDeviceUID);
</span><span class="cx"> }
</span><ins>+
+void WebPage::didCompleteUserMediaPermissionCheck(uint64_t userMediaID, bool allowed)
+{
+    m_userMediaPermissionRequestManager.didCompleteUserMediaPermissionCheck(userMediaID, allowed);
+}
</ins><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx"> #if !PLATFORM(IOS)
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebPageWebPageh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h (193943 => 193944)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h        2015-12-11 04:03:28 UTC (rev 193943)
+++ trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h        2015-12-11 04:06:05 UTC (rev 193944)
</span><span class="lines">@@ -1105,6 +1105,7 @@
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(MEDIA_STREAM)
</span><span class="cx">     WK_EXPORT void didReceiveUserMediaPermissionDecision(uint64_t userMediaID, bool allowed, const String&amp; audioDeviceUID, const String&amp; videoDeviceUID);
</span><ins>+    WK_EXPORT void didCompleteUserMediaPermissionCheck(uint64_t userMediaID, bool allowed);
</ins><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx">     void advanceToNextMisspelling(bool startBeforeSelection);
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebPageWebPagemessagesin"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/WebPage/WebPage.messages.in (193943 => 193944)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebPage/WebPage.messages.in        2015-12-11 04:03:28 UTC (rev 193943)
+++ trunk/Source/WebKit2/WebProcess/WebPage/WebPage.messages.in        2015-12-11 04:06:05 UTC (rev 193944)
</span><span class="lines">@@ -282,6 +282,7 @@
</span><span class="cx"> #if ENABLE(MEDIA_STREAM)
</span><span class="cx">     # MediaSteam
</span><span class="cx">     DidReceiveUserMediaPermissionDecision(uint64_t userMediaID, bool allowed, String audioDeviceUID, String videoDeviceUID)
</span><ins>+    DidCompleteUserMediaPermissionCheck(uint64_t userMediaID, bool allowed)
</ins><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx">     # Notification
</span></span></pre></div>
<a id="trunkToolsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Tools/ChangeLog (193943 => 193944)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/ChangeLog        2015-12-11 04:03:28 UTC (rev 193943)
+++ trunk/Tools/ChangeLog        2015-12-11 04:06:05 UTC (rev 193944)
</span><span class="lines">@@ -1,3 +1,27 @@
</span><ins>+2015-12-10  Eric Carlson  &lt;eric.carlson@apple.com&gt;
+
+        [MediaStream] Expose media capture devices persistent permissions to WebCore
+        https://bugs.webkit.org/show_bug.cgi?id=152087
+
+        Add support for the new user media permission checker page UI client method.
+
+        Reviewed by Chris Dumez.
+
+        * WebKitTestRunner/TestController.cpp:
+        (WTR::decidePolicyForUserMediaPermissionRequest):
+        (WTR::checkUserMediaPermissionForOrigin):
+        (WTR::TestController::createOtherPage): Add checkUserMediaPermissionForOrigin.
+        (WTR::TestController::createWebViewWithOptions): Ditto.
+        (WTR::TestController::resetStateToConsistentValues): Clear m_userMediaOriginPermissions.
+        (WTR::originUserVisibleName): New, create a string for the origin.
+        (WTR::TestController::handleCheckOfUserMediaPermissionForOrigin): Set the WKUserMediaPermissionCheckRef
+          according to the state of the origin permission map.
+        (WTR::TestController::handleUserMediaPermissionRequest): Remember both the origin and the
+          request so we can update the origin permission map in decidePolicyForUserMediaPermissionRequestIfPossible.
+        (WTR::TestController::decidePolicyForUserMediaPermissionRequestIfPossible): Update the
+          origin permission map.
+        * WebKitTestRunner/TestController.h:
+
</ins><span class="cx"> 2015-12-10  Alex Christensen  &lt;achristensen@webkit.org&gt;
</span><span class="cx"> 
</span><span class="cx">         REGRESSION (r192796) WKBundlePageResourceLoadClient should be able to setHTTPBody in willSendRequestForFrame
</span></span></pre></div>
<a id="trunkToolsWebKitTestRunnerTestControllercpp"></a>
<div class="modfile"><h4>Modified: trunk/Tools/WebKitTestRunner/TestController.cpp (193943 => 193944)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/WebKitTestRunner/TestController.cpp        2015-12-11 04:03:28 UTC (rev 193943)
+++ trunk/Tools/WebKitTestRunner/TestController.cpp        2015-12-11 04:06:05 UTC (rev 193944)
</span><span class="lines">@@ -51,6 +51,8 @@
</span><span class="cx"> #include &lt;WebKit/WKPreferencesRefPrivate.h&gt;
</span><span class="cx"> #include &lt;WebKit/WKProtectionSpace.h&gt;
</span><span class="cx"> #include &lt;WebKit/WKRetainPtr.h&gt;
</span><ins>+#include &lt;WebKit/WKSecurityOriginRef.h&gt;
+#include &lt;WebKit/WKUserMediaPermissionCheck.h&gt;
</ins><span class="cx"> #include &lt;algorithm&gt;
</span><span class="cx"> #include &lt;cstdio&gt;
</span><span class="cx"> #include &lt;ctype.h&gt;
</span><span class="lines">@@ -201,11 +203,16 @@
</span><span class="cx">     TestController::singleton().handleGeolocationPermissionRequest(permissionRequest);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static void decidePolicyForUserMediaPermissionRequest(WKPageRef, WKFrameRef, WKSecurityOriginRef, WKUserMediaPermissionRequestRef permissionRequest, const void* clientInfo)
</del><ins>+static void decidePolicyForUserMediaPermissionRequest(WKPageRef, WKFrameRef, WKSecurityOriginRef origin, WKUserMediaPermissionRequestRef permissionRequest, const void* clientInfo)
</ins><span class="cx"> {
</span><del>-    TestController::singleton().handleUserMediaPermissionRequest(permissionRequest);
</del><ins>+    TestController::singleton().handleUserMediaPermissionRequest(origin, permissionRequest);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><ins>+static void checkUserMediaPermissionForOrigin(WKPageRef, WKFrameRef, WKSecurityOriginRef origin, WKUserMediaPermissionCheckRef checkRequest, const void*)
+{
+    TestController::singleton().handleCheckOfUserMediaPermissionForOrigin(origin, checkRequest);
+}
+
</ins><span class="cx"> WKPageRef TestController::createOtherPage(WKPageRef oldPage, WKPageConfigurationRef configuration, WKNavigationActionRef navigationAction, WKWindowFeaturesRef windowFeatures, const void *clientInfo)
</span><span class="cx"> {
</span><span class="cx">     PlatformWebView* parentView = static_cast&lt;PlatformWebView*&gt;(const_cast&lt;void*&gt;(clientInfo));
</span><span class="lines">@@ -277,7 +284,8 @@
</span><span class="cx">         createOtherPage,
</span><span class="cx">         0, // runJavaScriptAlert
</span><span class="cx">         0, // runJavaScriptConfirm
</span><del>-        0  // runJavaScriptPrompt
</del><ins>+        0, // runJavaScriptPrompt
+        checkUserMediaPermissionForOrigin,
</ins><span class="cx">     };
</span><span class="cx">     WKPageSetPageUIClient(newPage, &amp;otherPageUIClient.base);
</span><span class="cx">     
</span><span class="lines">@@ -540,6 +548,7 @@
</span><span class="cx">         0, // runJavaScriptAlert
</span><span class="cx">         0, // runJavaScriptConfirm
</span><span class="cx">         0, // runJavaScriptPrompt
</span><ins>+        checkUserMediaPermissionForOrigin,
</ins><span class="cx">     };
</span><span class="cx">     WKPageSetPageUIClient(m_mainWebView-&gt;page(), &amp;pageUIClient.base);
</span><span class="cx"> 
</span><span class="lines">@@ -744,6 +753,7 @@
</span><span class="cx"> 
</span><span class="cx">     // Reset UserMedia permissions.
</span><span class="cx">     m_userMediaPermissionRequests.clear();
</span><ins>+    m_userMediaOriginPermissions = nullptr;
</ins><span class="cx">     m_isUserMediaPermissionSet = false;
</span><span class="cx">     m_isUserMediaPermissionAllowed = false;
</span><span class="cx"> 
</span><span class="lines">@@ -1642,9 +1652,38 @@
</span><span class="cx">     decidePolicyForUserMediaPermissionRequestIfPossible();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void TestController::handleUserMediaPermissionRequest(WKUserMediaPermissionRequestRef userMediaPermissionRequest)
</del><ins>+static WKStringRef originUserVisibleName(WKSecurityOriginRef origin)
</ins><span class="cx"> {
</span><del>-    m_userMediaPermissionRequests.append(userMediaPermissionRequest);
</del><ins>+    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 (port)
+        userVisibleName = String::format(&quot;%s://%s:%d&quot;, protocol.c_str(), host.c_str(), port);
+    else
+        userVisibleName = String::format(&quot;%s://%s&quot;, protocol.c_str(), host.c_str());
+
+    return WKStringCreateWithUTF8CString(userVisibleName.utf8().data());
+}
+
+void TestController::handleCheckOfUserMediaPermissionForOrigin(WKSecurityOriginRef origin, const WKUserMediaPermissionCheckRef&amp; checkRequest)
+{
+    bool allowed = false;
+
+    if (m_userMediaOriginPermissions) {
+        WKRetainPtr&lt;WKStringRef&gt; originString = originUserVisibleName(origin);
+        WKBooleanRef value = static_cast&lt;WKBooleanRef&gt;(WKDictionaryGetItemForKey(m_userMediaOriginPermissions.get(), originString.get()));
+        if (WKGetTypeID(value) == WKBooleanGetTypeID())
+            allowed = WKBooleanGetValue(value);
+    }
+
+    WKUserMediaPermissionCheckSetHasPersistentPermission(checkRequest, allowed);
+}
+
+void TestController::handleUserMediaPermissionRequest(WKSecurityOriginRef origin, WKUserMediaPermissionRequestRef request)
+{
+    m_userMediaPermissionRequests.append(std::make_pair(origin, request));
</ins><span class="cx">     decidePolicyForUserMediaPermissionRequestIfPossible();
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -1653,10 +1692,18 @@
</span><span class="cx">     if (!m_isUserMediaPermissionSet)
</span><span class="cx">         return;
</span><span class="cx"> 
</span><del>-    for (auto&amp; request : m_userMediaPermissionRequests) {
-        WKRetainPtr&lt;WKArrayRef&gt; audioDeviceUIDs = WKUserMediaPermissionRequestAudioDeviceUIDs(request.get());
-        WKRetainPtr&lt;WKArrayRef&gt; videoDeviceUIDs = WKUserMediaPermissionRequestVideoDeviceUIDs(request.get());
</del><ins>+    for (auto&amp; pair : m_userMediaPermissionRequests) {
+        auto origin = pair.first.get();
+        auto request = pair.second.get();
+        WKRetainPtr&lt;WKArrayRef&gt; audioDeviceUIDs = WKUserMediaPermissionRequestAudioDeviceUIDs(request);
+        WKRetainPtr&lt;WKArrayRef&gt; videoDeviceUIDs = WKUserMediaPermissionRequestVideoDeviceUIDs(request);
</ins><span class="cx"> 
</span><ins>+        WKRetainPtr&lt;WKStringRef&gt; originString = adoptWK(originUserVisibleName(origin));
+        if (!m_userMediaOriginPermissions)
+            m_userMediaOriginPermissions = adoptWK(WKMutableDictionaryCreate());
+        WKRetainPtr&lt;WKBooleanRef&gt; allowed = adoptWK(WKBooleanCreate(m_isUserMediaPermissionAllowed));
+        WKDictionarySetItem(m_userMediaOriginPermissions.get(), originString.get(), allowed.get());
+
</ins><span class="cx">         if (m_isUserMediaPermissionAllowed &amp;&amp; (WKArrayGetSize(videoDeviceUIDs.get()) || WKArrayGetSize(audioDeviceUIDs.get()))) {
</span><span class="cx">             WKRetainPtr&lt;WKStringRef&gt; videoDeviceUID;
</span><span class="cx">             if (WKArrayGetSize(videoDeviceUIDs.get()))
</span><span class="lines">@@ -1670,10 +1717,10 @@
</span><span class="cx">             else
</span><span class="cx">                 audioDeviceUID = WKStringCreateWithUTF8CString(&quot;&quot;);
</span><span class="cx"> 
</span><del>-            WKUserMediaPermissionRequestAllow(request.get(), audioDeviceUID.get(), videoDeviceUID.get());
</del><ins>+            WKUserMediaPermissionRequestAllow(request, audioDeviceUID.get(), videoDeviceUID.get());
</ins><span class="cx"> 
</span><span class="cx">         } else
</span><del>-            WKUserMediaPermissionRequestDeny(request.get());
</del><ins>+            WKUserMediaPermissionRequestDeny(request);
</ins><span class="cx">     }
</span><span class="cx">     m_userMediaPermissionRequests.clear();
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkToolsWebKitTestRunnerTestControllerh"></a>
<div class="modfile"><h4>Modified: trunk/Tools/WebKitTestRunner/TestController.h (193943 => 193944)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/WebKitTestRunner/TestController.h        2015-12-11 04:03:28 UTC (rev 193943)
+++ trunk/Tools/WebKitTestRunner/TestController.h        2015-12-11 04:06:05 UTC (rev 193944)
</span><span class="lines">@@ -32,6 +32,7 @@
</span><span class="cx"> #include &lt;WebKit/WKRetainPtr.h&gt;
</span><span class="cx"> #include &lt;string&gt;
</span><span class="cx"> #include &lt;vector&gt;
</span><ins>+#include &lt;wtf/HashMap.h&gt;
</ins><span class="cx"> #include &lt;wtf/Vector.h&gt;
</span><span class="cx"> 
</span><span class="cx"> OBJC_CLASS WKWebViewConfiguration;
</span><span class="lines">@@ -95,7 +96,8 @@
</span><span class="cx"> 
</span><span class="cx">     // MediaStream.
</span><span class="cx">     void setUserMediaPermission(bool);
</span><del>-    void handleUserMediaPermissionRequest(WKUserMediaPermissionRequestRef);
</del><ins>+    void handleUserMediaPermissionRequest(WKSecurityOriginRef, WKUserMediaPermissionRequestRef);
+    void handleCheckOfUserMediaPermissionForOrigin(WKSecurityOriginRef, const WKUserMediaPermissionCheckRef&amp;);
</ins><span class="cx"> 
</span><span class="cx">     // Policy delegate.
</span><span class="cx">     void setCustomPolicyDelegate(bool enabled, bool permissive);
</span><span class="lines">@@ -282,7 +284,11 @@
</span><span class="cx">     bool m_isGeolocationPermissionSet;
</span><span class="cx">     bool m_isGeolocationPermissionAllowed;
</span><span class="cx"> 
</span><del>-    Vector&lt;WKRetainPtr&lt;WKUserMediaPermissionRequestRef&gt;&gt; m_userMediaPermissionRequests;
</del><ins>+    WKRetainPtr&lt;WKMutableDictionaryRef&gt; m_userMediaOriginPermissions;
+
+    typedef Vector&lt;std::pair&lt;WKRetainPtr&lt;WKSecurityOriginRef&gt;, WKRetainPtr&lt;WKUserMediaPermissionRequestRef&gt;&gt;&gt; PermissionRequestList;
+    PermissionRequestList m_userMediaPermissionRequests;
+
</ins><span class="cx">     bool m_isUserMediaPermissionSet;
</span><span class="cx">     bool m_isUserMediaPermissionAllowed;
</span><span class="cx"> 
</span></span></pre>
</div>
</div>

</body>
</html>