<!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>[207463] 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/207463">207463</a></dd>
<dt>Author</dt> <dd>eric.carlson@apple.com</dd>
<dt>Date</dt> <dd>2016-10-18 07:53:06 -0700 (Tue, 18 Oct 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>
Source/WebCore:
[MediaStream] Resolve constraints and enumerate devices in the UI process
https://bugs.webkit.org/show_bug.cgi?id=162147
&lt;rdar://problem/28803569&gt;

Reviewed by Darin Adler.

Restructure gUM constraint validation and MediaDevices.enumerateDevices so all media device
access happens in the UI process.

No new tests, updated results of existing tests.

* CMakeLists.txt: Add MediaDevicesEnumerationRequest.cpp, delete UserMediaPermissionCheck.cpp.

* Modules/mediastream/MediaConstraintsImpl.cpp:
(WebCore::MediaConstraintsImpl::create): Only create from MediaConstraintsData.
(WebCore::MediaConstraintsImpl::initialize): Deleted.
* Modules/mediastream/MediaConstraintsImpl.h:

* Modules/mediastream/MediaDevicesEnumerationRequest.cpp: Added.
(WebCore::MediaDevicesEnumerationRequest::create):
(WebCore::MediaDevicesEnumerationRequest::MediaDevicesEnumerationRequest):
(WebCore::MediaDevicesEnumerationRequest::~MediaDevicesEnumerationRequest):
(WebCore::MediaDevicesEnumerationRequest::userMediaDocumentOrigin):
(WebCore::MediaDevicesEnumerationRequest::topLevelDocumentOrigin):
(WebCore::MediaDevicesEnumerationRequest::contextDestroyed):
(WebCore::MediaDevicesEnumerationRequest::start):
(WebCore::MediaDevicesEnumerationRequest::cancel):
(WebCore::MediaDevicesEnumerationRequest::setDeviceInfo):
(WebCore::MediaDevicesEnumerationRequest::finish):
* Modules/mediastream/MediaDevicesEnumerationRequest.h: Added.

* Modules/mediastream/MediaDevicesRequest.cpp:
(WebCore::MediaDevicesRequest::~MediaDevicesRequest): Clear the enumeration request.
(WebCore::MediaDevicesRequest::contextDestroyed): Ditto.
(WebCore::MediaDevicesRequest::start): Create and use a MediaDevicesEnumerationRequest.
(WebCore::MediaDevicesRequest::didCompletePermissionCheck): Deleted.
* Modules/mediastream/MediaDevicesRequest.h:

* Modules/mediastream/UserMediaClient.h:
* Modules/mediastream/UserMediaController.h:
(WebCore::UserMediaController::enumerateMediaDevices): New.
(WebCore::UserMediaController::cancelMediaDevicesEnumerationRequest): New.
(WebCore::UserMediaController::checkUserMediaPermission): Deleted.
(WebCore::UserMediaController::cancelUserMediaPermissionCheck): Deleted.

* Modules/mediastream/UserMediaPermissionCheck.h: Deleted.
* Modules/mediastream/UserMediaPermissionCheck.cpp: Deleted.

* Modules/mediastream/UserMediaRequest.cpp:
(WebCore::UserMediaRequest::UserMediaRequest):
(WebCore::UserMediaRequest::start):
(WebCore::UserMediaRequest::allow):
(WebCore::UserMediaRequest::deny):
(WebCore::UserMediaRequest::constraintsValidated): Deleted.
(WebCore::UserMediaRequest::userMediaAccessGranted): Deleted.
(WebCore::UserMediaRequest::userMediaAccessDenied): Deleted.
(WebCore::UserMediaRequest::constraintsInvalid): Deleted.
(WebCore::UserMediaRequest::didCreateStream): Deleted.
(WebCore::UserMediaRequest::failedToCreateStreamWithConstraintsError): Deleted.
(WebCore::UserMediaRequest::failedToCreateStreamWithPermissionError): Deleted.
* Modules/mediastream/UserMediaRequest.h:

* WebCore.xcodeproj/project.pbxproj: Add MediaDevicesEnumerationRequest.*.

* platform/mediastream/CaptureDevice.h:
(WebCore::CaptureDevice::CaptureDevice):
(WebCore::CaptureDevice::setPersistentId): Add setter for argument decoder.
(WebCore::CaptureDevice::setLabel): Ditto.
(WebCore::CaptureDevice::setGroupId): Ditto.
(WebCore::CaptureDevice::setKind): Ditto.

* platform/mediastream/CaptureDeviceManager.h: Remove unnecessary include.

* platform/mediastream/MediaConstraints.h:
(WebCore::MediaConstraint::encode): New.
(WebCore::MediaConstraint::decode): Ditto.
(WebCore::NumericConstraint::encode): Ditto.
(WebCore::NumericConstraint::decode): Ditto.

* platform/mediastream/MediaStreamCreationClient.h: Deleted.

* platform/mediastream/RealtimeMediaSourceCenter.h: Use completion handlers instead of client interface.

* platform/mediastream/mac/AVCaptureDeviceManager.mm:
(WebCore::AVCaptureDeviceManager::refreshCaptureDeviceList): Drive-by fix: don't initialize
group id, we don't support it.

* platform/mediastream/mac/RealtimeMediaSourceCenterMac.cpp:
(WebCore::RealtimeMediaSourceCenterMac::validateRequestConstraints): Update for interface change.
(WebCore::RealtimeMediaSourceCenterMac::createMediaStream): Ditto.
* platform/mediastream/mac/RealtimeMediaSourceCenterMac.h:

* platform/mediastream/openwebrtc/RealtimeMediaSourceCenterOwr.cpp:
(WebCore::RealtimeMediaSourceCenterOwr::validateRequestConstraints): Ditto.
(WebCore::RealtimeMediaSourceCenterOwr::createMediaStream): Ditto.
(WebCore::RealtimeMediaSourceCenterOwr::mediaSourcesAvailable): Ditto.
* platform/mediastream/openwebrtc/RealtimeMediaSourceCenterOwr.h:

* platform/mock/MockRealtimeMediaSourceCenter.cpp:
(WebCore::MockRealtimeMediaSourceCenter::validateRequestConstraints): Ditto.
(WebCore::MockRealtimeMediaSourceCenter::createMediaStream): Ditto.
* platform/mock/MockRealtimeMediaSourceCenter.h:

Source/WebKit:
Fix CMake build.

Patch by Alex Christensen &lt;achristensen@webkit.org&gt; on 2016-10-14

* PlatformMac.cmake:

Source/WebKit2:
[MediaStream] Resolve constraints and enumerate devices in the UI process
https://bugs.webkit.org/show_bug.cgi?id=162147
&lt;rdar://problem/28803569&gt;

Reviewed by Darin Adler.
        
Restructure gUM constraint validation and MediaDevices.enumerateDevices so all media device
access happens in the UI process.

* Scripts/webkit/messages.py:
(headers_for_type): Special case MediaConstraintsData.

* Shared/WebCoreArgumentCoders.cpp:
(IPC::encodeMediaTrackConstraintSetMap): MediaTrackConstraintSetMap encoder.
(IPC::ArgumentCoder&lt;MediaConstraintsData&gt;::encode): MediaConstraintsData encoder.
(IPC::decodeMediaTrackConstraintSetMap): MediaTrackConstraintSetMap decoder.
(IPC::ArgumentCoder&lt;MediaConstraintsData&gt;::decode): MediaConstraintsData decoder.
(IPC::ArgumentCoder&lt;CaptureDevice&gt;::encode): CaptureDevice enoder.
(IPC::ArgumentCoder&lt;CaptureDevice&gt;::decode): CaptureDevice decoder.
* Shared/WebCoreArgumentCoders.h:

* UIProcess/API/APIUIClient.h:  Remove UserMediaPermissionCheckProxy forward declaration.

* UIProcess/API/C/WKUserMediaPermissionRequest.cpp:
(toWK): Translate UserMediaPermissionRequestDenialReason to UserMediaAccessDenialReason.
(WKUserMediaPermissionRequestDeny): Add &quot;reason&quot; parameter.
* UIProcess/API/C/WKUserMediaPermissionRequest.h:

* UIProcess/UserMediaPermissionRequestManagerProxy.cpp:
(WebKit::UserMediaPermissionRequestManagerProxy::invalidateRequests): Invalidate pending device requests.
(WebKit::UserMediaPermissionRequestManagerProxy::createRequest): Make private.
(WebKit::toWebCore): Map from UserMediaAccessDenialReason to MediaAccessDenialReason, cast to
  uint64_t to pass to web process.
(WebKit::UserMediaPermissionRequestManagerProxy::denyRequest): Send to web process.
(WebKit::UserMediaPermissionRequestManagerProxy::userMediaAccessWasGranted): Ditto.
(WebKit::UserMediaPermissionRequestManagerProxy::requestUserMediaPermissionForFrame): Validate
  constraints and make sure gUM is enabled before prompting user.
(WebKit::UserMediaPermissionRequestManagerProxy::enumerateMediaDevicesForFrame): New.
(WebKit::UserMediaPermissionRequestManagerProxy::didCompleteUserMediaPermissionCheck): Send 
  results of device enumeration to web process.
(WebKit::UserMediaPermissionRequestManagerProxy::didReceiveUserMediaPermissionDecision): Deleted.
(WebKit::UserMediaPermissionRequestManagerProxy::createUserMediaPermissionCheck): Deleted.
* UIProcess/UserMediaPermissionRequestManagerProxy.h:

* UIProcess/UserMediaPermissionRequestProxy.cpp:
(WebKit::UserMediaPermissionRequestProxy::allow):
(WebKit::UserMediaPermissionRequestProxy::deny): Take &quot;reason&quot; parameter.
* UIProcess/UserMediaPermissionRequestProxy.h:

* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::requestUserMediaPermissionForFrame):
(WebKit::WebPageProxy::enumerateMediaDevicesForFrame):
(WebKit::WebPageProxy::checkUserMediaPermissionForFrame): Deleted.
* UIProcess/WebPageProxy.h:
* UIProcess/WebPageProxy.messages.in:

* WebProcess/MediaStream/UserMediaPermissionRequestManager.cpp:
(WebKit::UserMediaPermissionRequestManager::startUserMediaRequest): userMediaAccessDenied -&gt; deny.
  Pass the audio and video constraints to the UI process.
(WebKit::UserMediaPermissionRequestManager::userMediaAccessWasGranted): 
(WebKit::UserMediaPermissionRequestManager::userMediaAccessWasDenied):
(WebKit::UserMediaPermissionRequestManager::enumerateMediaDevices): Send the enumeration request
  to the UI process.
(WebKit::UserMediaPermissionRequestManager::cancelMediaDevicesEnumeration):
(WebKit::UserMediaPermissionRequestManager::didCompleteMediaDeviceEnumeration):
(WebKit::UserMediaPermissionRequestManager::didReceiveUserMediaPermissionDecision): Deleted.
(WebKit::UserMediaPermissionRequestManager::startUserMediaPermissionCheck): Deleted.
(WebKit::UserMediaPermissionRequestManager::cancelUserMediaPermissionCheck): Deleted.
(WebKit::UserMediaPermissionRequestManager::didCompleteUserMediaPermissionCheck): Deleted.
* WebProcess/MediaStream/UserMediaPermissionRequestManager.h:

* WebProcess/WebCoreSupport/WebUserMediaClient.cpp:
(WebKit::WebUserMediaClient::enumerateMediaDevices): New.
(WebKit::WebUserMediaClient::cancelMediaDevicesEnumerationRequest): New.
(WebKit::WebUserMediaClient::checkUserMediaPermission): Deleted.
(WebKit::WebUserMediaClient::cancelUserMediaPermissionCheck): Deleted.
* WebProcess/WebCoreSupport/WebUserMediaClient.h:

* WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::userMediaAccessWasGranted): New.
(WebKit::WebPage::userMediaAccessWasDenied): Ditto.
(WebKit::WebPage::didCompleteMediaDeviceEnumeration):
(WebKit::WebPage::didReceiveUserMediaPermissionDecision): Deleted.
(WebKit::WebPage::didCompleteUserMediaPermissionCheck): Deleted.
* WebProcess/WebPage/WebPage.h:
* WebProcess/WebPage/WebPage.messages.in:

Tools:
[MediaStream] Resolve constraints and enumerate devices in the UI process
https://bugs.webkit.org/show_bug.cgi?id=162147
&lt;rdar://problem/28803569&gt;

Reviewed by Darin Adler.

* WebKitTestRunner/TestController.cpp:
(WTR::TestController::resetPreferencesToConsistentValues): Enable mock capture devices.
(WTR::TestController::decidePolicyForUserMediaPermissionRequestIfPossible): Update for API changes.

LayoutTests:
[MediaStream] Resolve constraints and enumerate devices in the UI process
https://bugs.webkit.org/show_bug.cgi?id=162147
&lt;rdar://problem/28803569&gt;

Reviewed by Darin Adler.

* fast/mediastream/getusermedia-expected.txt: Updated.
* fast/mediastream/getusermedia.html: Ditto.
* fast/mediastream/mock-media-source-expected.txt: Ditto.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsfastmediastreamgetusermediaexpectedtxt">trunk/LayoutTests/fast/mediastream/getusermedia-expected.txt</a></li>
<li><a href="#trunkLayoutTestsfastmediastreamgetusermediahtml">trunk/LayoutTests/fast/mediastream/getusermedia.html</a></li>
<li><a href="#trunkLayoutTestsfastmediastreammockmediasourceexpectedtxt">trunk/LayoutTests/fast/mediastream/mock-media-source-expected.txt</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="#trunkSourceWebCoreModulesmediastreamMediaConstraintsImplcpp">trunk/Source/WebCore/Modules/mediastream/MediaConstraintsImpl.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesmediastreamMediaConstraintsImplh">trunk/Source/WebCore/Modules/mediastream/MediaConstraintsImpl.h</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="#trunkSourceWebCoreModulesmediastreamUserMediaRequestcpp">trunk/Source/WebCore/Modules/mediastream/UserMediaRequest.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesmediastreamUserMediaRequesth">trunk/Source/WebCore/Modules/mediastream/UserMediaRequest.h</a></li>
<li><a href="#trunkSourceWebCoreWebCorexcodeprojprojectpbxproj">trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceWebCoreplatformmediastreamCaptureDeviceh">trunk/Source/WebCore/platform/mediastream/CaptureDevice.h</a></li>
<li><a href="#trunkSourceWebCoreplatformmediastreamCaptureDeviceManagerh">trunk/Source/WebCore/platform/mediastream/CaptureDeviceManager.h</a></li>
<li><a href="#trunkSourceWebCoreplatformmediastreamMediaConstraintscpp">trunk/Source/WebCore/platform/mediastream/MediaConstraints.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformmediastreamMediaConstraintsh">trunk/Source/WebCore/platform/mediastream/MediaConstraints.h</a></li>
<li><a href="#trunkSourceWebCoreplatformmediastreamRealtimeMediaSourceCenterh">trunk/Source/WebCore/platform/mediastream/RealtimeMediaSourceCenter.h</a></li>
<li><a href="#trunkSourceWebCoreplatformmediastreammacAVCaptureDeviceManagermm">trunk/Source/WebCore/platform/mediastream/mac/AVCaptureDeviceManager.mm</a></li>
<li><a href="#trunkSourceWebCoreplatformmediastreammacRealtimeMediaSourceCenterMaccpp">trunk/Source/WebCore/platform/mediastream/mac/RealtimeMediaSourceCenterMac.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformmediastreammacRealtimeMediaSourceCenterMach">trunk/Source/WebCore/platform/mediastream/mac/RealtimeMediaSourceCenterMac.h</a></li>
<li><a href="#trunkSourceWebCoreplatformmediastreamopenwebrtcRealtimeMediaSourceCenterOwrcpp">trunk/Source/WebCore/platform/mediastream/openwebrtc/RealtimeMediaSourceCenterOwr.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformmediastreamopenwebrtcRealtimeMediaSourceCenterOwrh">trunk/Source/WebCore/platform/mediastream/openwebrtc/RealtimeMediaSourceCenterOwr.h</a></li>
<li><a href="#trunkSourceWebCoreplatformmockMockRealtimeMediaSourceCentercpp">trunk/Source/WebCore/platform/mock/MockRealtimeMediaSourceCenter.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformmockMockRealtimeMediaSourceCenterh">trunk/Source/WebCore/platform/mock/MockRealtimeMediaSourceCenter.h</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="#trunkSourceWebKit2ChangeLog">trunk/Source/WebKit2/ChangeLog</a></li>
<li><a href="#trunkSourceWebKit2Scriptswebkitmessagespy">trunk/Source/WebKit2/Scripts/webkit/messages.py</a></li>
<li><a href="#trunkSourceWebKit2SharedWebCoreArgumentCoderscpp">trunk/Source/WebKit2/Shared/WebCoreArgumentCoders.cpp</a></li>
<li><a href="#trunkSourceWebKit2SharedWebCoreArgumentCodersh">trunk/Source/WebKit2/Shared/WebCoreArgumentCoders.h</a></li>
<li><a href="#trunkSourceWebKit2UIProcessAPIAPIUIClienth">trunk/Source/WebKit2/UIProcess/API/APIUIClient.h</a></li>
<li><a href="#trunkSourceWebKit2UIProcessAPICWKUserMediaPermissionRequestcpp">trunk/Source/WebKit2/UIProcess/API/C/WKUserMediaPermissionRequest.cpp</a></li>
<li><a href="#trunkSourceWebKit2UIProcessAPICWKUserMediaPermissionRequesth">trunk/Source/WebKit2/UIProcess/API/C/WKUserMediaPermissionRequest.h</a></li>
<li><a href="#trunkSourceWebKit2UIProcessAPIgtkWebKitUserMediaPermissionRequestcpp">trunk/Source/WebKit2/UIProcess/API/gtk/WebKitUserMediaPermissionRequest.cpp</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="#trunkSourceWebKit2UIProcessUserMediaPermissionRequestProxycpp">trunk/Source/WebKit2/UIProcess/UserMediaPermissionRequestProxy.cpp</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="#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>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreModulesmediastreamMediaDevicesEnumerationRequestcpp">trunk/Source/WebCore/Modules/mediastream/MediaDevicesEnumerationRequest.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesmediastreamMediaDevicesEnumerationRequesth">trunk/Source/WebCore/Modules/mediastream/MediaDevicesEnumerationRequest.h</a></li>
</ul>

<h3>Removed 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="#trunkSourceWebCoreplatformmediastreamMediaStreamCreationClienth">trunk/Source/WebCore/platform/mediastream/MediaStreamCreationClient.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (207462 => 207463)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2016-10-18 13:15:40 UTC (rev 207462)
+++ trunk/LayoutTests/ChangeLog        2016-10-18 14:53:06 UTC (rev 207463)
</span><span class="lines">@@ -1,3 +1,15 @@
</span><ins>+2016-10-18  Eric Carlson  &lt;eric.carlson@apple.com&gt;
+
+        [MediaStream] Resolve constraints and enumerate devices in the UI process
+        https://bugs.webkit.org/show_bug.cgi?id=162147
+        &lt;rdar://problem/28803569&gt;
+
+        Reviewed by Darin Adler.
+
+        * fast/mediastream/getusermedia-expected.txt: Updated.
+        * fast/mediastream/getusermedia.html: Ditto.
+        * fast/mediastream/mock-media-source-expected.txt: Ditto.
+
</ins><span class="cx"> 2016-10-18  Caitlin Potter  &lt;caitp@igalia.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [JSC] ES6 Method functions should not have prototype
</span></span></pre></div>
<a id="trunkLayoutTestsfastmediastreamgetusermediaexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/fast/mediastream/getusermedia-expected.txt (207462 => 207463)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/mediastream/getusermedia-expected.txt        2016-10-18 13:15:40 UTC (rev 207462)
+++ trunk/LayoutTests/fast/mediastream/getusermedia-expected.txt        2016-10-18 14:53:06 UTC (rev 207463)
</span><span class="lines">@@ -28,7 +28,8 @@
</span><span class="cx"> PASS navigator.webkitGetUserMedia({audio:true, video:{width:{exact:11}}}, gotStreamInError, null); threw exception TypeError: Argument 3 ('errorCallback') to Navigator.webkitGetUserMedia must be a function.
</span><span class="cx"> PASS navigator.webkitGetUserMedia({audio:true, video:{width:{exact:11}}}, gotStreamInError, error1); did not throw exception.
</span><span class="cx"> PASS Error callback called.
</span><del>-FAIL errorArg.name should be OverConstrainedError. Was DataError.
</del><ins>+FAIL errorArg.name should be OverconstrainedError. Was Error.
+PASS errorArg.message is &quot;Invalid constraint&quot;
</ins><span class="cx"> PASS navigator.webkitGetUserMedia({audio:{volume:{exact:1}}, video:true}, gotStream5, 0); threw exception TypeError: Argument 3 ('errorCallback') to Navigator.webkitGetUserMedia must be a function.
</span><span class="cx"> PASS navigator.webkitGetUserMedia({audio:{volume:{exact:1}}, video:true}, gotStream5, error); did not throw exception.
</span><span class="cx"> PASS Stream generated.
</span></span></pre></div>
<a id="trunkLayoutTestsfastmediastreamgetusermediahtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/fast/mediastream/getusermedia.html (207462 => 207463)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/mediastream/getusermedia.html        2016-10-18 13:15:40 UTC (rev 207462)
+++ trunk/LayoutTests/fast/mediastream/getusermedia.html        2016-10-18 14:53:06 UTC (rev 207463)
</span><span class="lines">@@ -44,7 +44,8 @@
</span><span class="cx">             function error1(e) {
</span><span class="cx">                 errorArg = e;
</span><span class="cx">                 testPassed('Error callback called.');
</span><del>-                shouldBeEqualToString('errorArg.name', 'OverConstrainedError');
</del><ins>+                shouldBeEqualToString('errorArg.name', 'OverconstrainedError');
+                shouldBeEqualToString('errorArg.message', 'Invalid constraint');
</ins><span class="cx"> 
</span><span class="cx">                 shouldThrow(&quot;navigator.webkitGetUserMedia({audio:{volume:{exact:1}}, video:true}, gotStream5, 0);&quot;);
</span><span class="cx">                 shouldNotThrow(&quot;navigator.webkitGetUserMedia({audio:{volume:{exact:1}}, video:true}, gotStream5, error);&quot;);
</span></span></pre></div>
<a id="trunkLayoutTestsfastmediastreammockmediasourceexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/fast/mediastream/mock-media-source-expected.txt (207462 => 207463)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/mediastream/mock-media-source-expected.txt        2016-10-18 13:15:40 UTC (rev 207462)
+++ trunk/LayoutTests/fast/mediastream/mock-media-source-expected.txt        2016-10-18 14:53:06 UTC (rev 207463)
</span><span class="lines">@@ -10,7 +10,7 @@
</span><span class="cx"> 
</span><span class="cx"> *** Disable mock capture devices
</span><span class="cx"> internals.setMockMediaCaptureDevicesEnabled(false)
</span><del>-PASS mediaDevices.getUserMedia() failed with NotAllowedError
</del><ins>+PASS mediaDevices.getUserMedia() failed with NotReadableError
</ins><span class="cx"> 
</span><span class="cx"> *** Enable mock capture devices
</span><span class="cx"> internals.setMockMediaCaptureDevicesEnabled(true)
</span></span></pre></div>
<a id="trunkSourceWebCoreCMakeListstxt"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/CMakeLists.txt (207462 => 207463)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/CMakeLists.txt        2016-10-18 13:15:40 UTC (rev 207462)
+++ trunk/Source/WebCore/CMakeLists.txt        2016-10-18 14:53:06 UTC (rev 207463)
</span><span class="lines">@@ -885,6 +885,7 @@
</span><span class="cx">     Modules/mediastream/MediaConstraintsImpl.cpp
</span><span class="cx">     Modules/mediastream/MediaDeviceInfo.cpp
</span><span class="cx">     Modules/mediastream/MediaDevices.cpp
</span><ins>+    Modules/mediastream/MediaDevicesEnumerationRequest.cpp
</ins><span class="cx">     Modules/mediastream/MediaDevicesRequest.cpp
</span><span class="cx">     Modules/mediastream/MediaEndpointPeerConnection.cpp
</span><span class="cx">     Modules/mediastream/MediaEndpointSessionDescription.cpp
</span><span class="lines">@@ -916,7 +917,6 @@
</span><span class="cx">     Modules/mediastream/RTCTrackEvent.cpp
</span><span class="cx">     Modules/mediastream/SDPProcessor.cpp
</span><span class="cx">     Modules/mediastream/UserMediaController.cpp
</span><del>-    Modules/mediastream/UserMediaPermissionCheck.cpp
</del><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 (207462 => 207463)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2016-10-18 13:15:40 UTC (rev 207462)
+++ trunk/Source/WebCore/ChangeLog        2016-10-18 14:53:06 UTC (rev 207463)
</span><span class="lines">@@ -1,3 +1,108 @@
</span><ins>+2016-10-18  Eric Carlson  &lt;eric.carlson@apple.com&gt;
+
+        [MediaStream] Resolve constraints and enumerate devices in the UI process
+        https://bugs.webkit.org/show_bug.cgi?id=162147
+        &lt;rdar://problem/28803569&gt;
+
+        Reviewed by Darin Adler.
+
+        Restructure gUM constraint validation and MediaDevices.enumerateDevices so all media device
+        access happens in the UI process.
+
+        No new tests, updated results of existing tests.
+
+        * CMakeLists.txt: Add MediaDevicesEnumerationRequest.cpp, delete UserMediaPermissionCheck.cpp.
+
+        * Modules/mediastream/MediaConstraintsImpl.cpp:
+        (WebCore::MediaConstraintsImpl::create): Only create from MediaConstraintsData.
+        (WebCore::MediaConstraintsImpl::initialize): Deleted.
+        * Modules/mediastream/MediaConstraintsImpl.h:
+
+        * Modules/mediastream/MediaDevicesEnumerationRequest.cpp: Added.
+        (WebCore::MediaDevicesEnumerationRequest::create):
+        (WebCore::MediaDevicesEnumerationRequest::MediaDevicesEnumerationRequest):
+        (WebCore::MediaDevicesEnumerationRequest::~MediaDevicesEnumerationRequest):
+        (WebCore::MediaDevicesEnumerationRequest::userMediaDocumentOrigin):
+        (WebCore::MediaDevicesEnumerationRequest::topLevelDocumentOrigin):
+        (WebCore::MediaDevicesEnumerationRequest::contextDestroyed):
+        (WebCore::MediaDevicesEnumerationRequest::start):
+        (WebCore::MediaDevicesEnumerationRequest::cancel):
+        (WebCore::MediaDevicesEnumerationRequest::setDeviceInfo):
+        (WebCore::MediaDevicesEnumerationRequest::finish):
+        * Modules/mediastream/MediaDevicesEnumerationRequest.h: Added.
+
+        * Modules/mediastream/MediaDevicesRequest.cpp:
+        (WebCore::MediaDevicesRequest::~MediaDevicesRequest): Clear the enumeration request.
+        (WebCore::MediaDevicesRequest::contextDestroyed): Ditto.
+        (WebCore::MediaDevicesRequest::start): Create and use a MediaDevicesEnumerationRequest.
+        (WebCore::MediaDevicesRequest::didCompletePermissionCheck): Deleted.
+        * Modules/mediastream/MediaDevicesRequest.h:
+
+        * Modules/mediastream/UserMediaClient.h:
+        * Modules/mediastream/UserMediaController.h:
+        (WebCore::UserMediaController::enumerateMediaDevices): New.
+        (WebCore::UserMediaController::cancelMediaDevicesEnumerationRequest): New.
+        (WebCore::UserMediaController::checkUserMediaPermission): Deleted.
+        (WebCore::UserMediaController::cancelUserMediaPermissionCheck): Deleted.
+
+        * Modules/mediastream/UserMediaPermissionCheck.h: Deleted.
+        * Modules/mediastream/UserMediaPermissionCheck.cpp: Deleted.
+
+        * Modules/mediastream/UserMediaRequest.cpp:
+        (WebCore::UserMediaRequest::UserMediaRequest):
+        (WebCore::UserMediaRequest::start):
+        (WebCore::UserMediaRequest::allow):
+        (WebCore::UserMediaRequest::deny):
+        (WebCore::UserMediaRequest::constraintsValidated): Deleted.
+        (WebCore::UserMediaRequest::userMediaAccessGranted): Deleted.
+        (WebCore::UserMediaRequest::userMediaAccessDenied): Deleted.
+        (WebCore::UserMediaRequest::constraintsInvalid): Deleted.
+        (WebCore::UserMediaRequest::didCreateStream): Deleted.
+        (WebCore::UserMediaRequest::failedToCreateStreamWithConstraintsError): Deleted.
+        (WebCore::UserMediaRequest::failedToCreateStreamWithPermissionError): Deleted.
+        * Modules/mediastream/UserMediaRequest.h:
+
+        * WebCore.xcodeproj/project.pbxproj: Add MediaDevicesEnumerationRequest.*.
+
+        * platform/mediastream/CaptureDevice.h:
+        (WebCore::CaptureDevice::CaptureDevice):
+        (WebCore::CaptureDevice::setPersistentId): Add setter for argument decoder.
+        (WebCore::CaptureDevice::setLabel): Ditto.
+        (WebCore::CaptureDevice::setGroupId): Ditto.
+        (WebCore::CaptureDevice::setKind): Ditto.
+
+        * platform/mediastream/CaptureDeviceManager.h: Remove unnecessary include.
+
+        * platform/mediastream/MediaConstraints.h:
+        (WebCore::MediaConstraint::encode): New.
+        (WebCore::MediaConstraint::decode): Ditto.
+        (WebCore::NumericConstraint::encode): Ditto.
+        (WebCore::NumericConstraint::decode): Ditto.
+
+        * platform/mediastream/MediaStreamCreationClient.h: Deleted.
+
+        * platform/mediastream/RealtimeMediaSourceCenter.h: Use completion handlers instead of client interface.
+
+        * platform/mediastream/mac/AVCaptureDeviceManager.mm:
+        (WebCore::AVCaptureDeviceManager::refreshCaptureDeviceList): Drive-by fix: don't initialize
+        group id, we don't support it.
+
+        * platform/mediastream/mac/RealtimeMediaSourceCenterMac.cpp:
+        (WebCore::RealtimeMediaSourceCenterMac::validateRequestConstraints): Update for interface change.
+        (WebCore::RealtimeMediaSourceCenterMac::createMediaStream): Ditto.
+        * platform/mediastream/mac/RealtimeMediaSourceCenterMac.h:
+
+        * platform/mediastream/openwebrtc/RealtimeMediaSourceCenterOwr.cpp:
+        (WebCore::RealtimeMediaSourceCenterOwr::validateRequestConstraints): Ditto.
+        (WebCore::RealtimeMediaSourceCenterOwr::createMediaStream): Ditto.
+        (WebCore::RealtimeMediaSourceCenterOwr::mediaSourcesAvailable): Ditto.
+        * platform/mediastream/openwebrtc/RealtimeMediaSourceCenterOwr.h:
+
+        * platform/mock/MockRealtimeMediaSourceCenter.cpp:
+        (WebCore::MockRealtimeMediaSourceCenter::validateRequestConstraints): Ditto.
+        (WebCore::MockRealtimeMediaSourceCenter::createMediaStream): Ditto.
+        * platform/mock/MockRealtimeMediaSourceCenter.h:
+
</ins><span class="cx"> 2016-10-18  Zan Dobersek  &lt;zdobersek@igalia.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [WebIDL] Support BufferSource
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesmediastreamMediaConstraintsImplcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/mediastream/MediaConstraintsImpl.cpp (207462 => 207463)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/mediastream/MediaConstraintsImpl.cpp        2016-10-18 13:15:40 UTC (rev 207462)
+++ trunk/Source/WebCore/Modules/mediastream/MediaConstraintsImpl.cpp        2016-10-18 14:53:06 UTC (rev 207463)
</span><span class="lines">@@ -1,5 +1,6 @@
</span><span class="cx"> /*
</span><span class="cx">  * Copyright (C) 2012 Google Inc. All rights reserved.
</span><ins>+ * Copyright (C) 2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -35,24 +36,19 @@
</span><span class="cx"> #include &quot;MediaConstraintsImpl.h&quot;
</span><span class="cx"> 
</span><span class="cx"> #include &quot;ArrayValue.h&quot;
</span><del>-#include &quot;Dictionary.h&quot;
</del><span class="cx"> #include &quot;ExceptionCode.h&quot;
</span><span class="cx"> #include &quot;Logging.h&quot;
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><del>-Ref&lt;MediaConstraintsImpl&gt; MediaConstraintsImpl::create()
-{
-    return adoptRef(*new MediaConstraintsImpl());
-}
-
</del><span class="cx"> Ref&lt;MediaConstraintsImpl&gt; MediaConstraintsImpl::create(MediaTrackConstraintSetMap&amp;&amp; mandatoryConstraints, Vector&lt;MediaTrackConstraintSetMap&gt;&amp;&amp; advancedConstraints, bool isValid)
</span><span class="cx"> {
</span><span class="cx">     return adoptRef(*new MediaConstraintsImpl(WTFMove(mandatoryConstraints), WTFMove(advancedConstraints), isValid));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-MediaConstraintsImpl::~MediaConstraintsImpl()
</del><ins>+Ref&lt;MediaConstraintsImpl&gt; MediaConstraintsImpl::create(const MediaConstraintsData&amp; data)
</ins><span class="cx"> {
</span><ins>+    return adoptRef(*new MediaConstraintsImpl(data));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesmediastreamMediaConstraintsImplh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/mediastream/MediaConstraintsImpl.h (207462 => 207463)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/mediastream/MediaConstraintsImpl.h        2016-10-18 13:15:40 UTC (rev 207462)
+++ trunk/Source/WebCore/Modules/mediastream/MediaConstraintsImpl.h        2016-10-18 14:53:06 UTC (rev 207463)
</span><span class="lines">@@ -39,32 +39,36 @@
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><del>-class ArrayValue;
-class Dictionary;
</del><ins>+struct MediaConstraintsData {
+    MediaTrackConstraintSetMap mandatoryConstraints;
+    Vector&lt;MediaTrackConstraintSetMap&gt; advancedConstraints;
+    bool isValid { false };
+};
</ins><span class="cx"> 
</span><span class="cx"> class MediaConstraintsImpl final : public MediaConstraints {
</span><span class="cx"> public:
</span><del>-    static Ref&lt;MediaConstraintsImpl&gt; create();
</del><span class="cx">     static Ref&lt;MediaConstraintsImpl&gt; create(MediaTrackConstraintSetMap&amp;&amp; mandatoryConstraints, Vector&lt;MediaTrackConstraintSetMap&gt;&amp;&amp; advancedConstraints, bool isValid);
</span><ins>+    WEBCORE_EXPORT static Ref&lt;MediaConstraintsImpl&gt; create(const MediaConstraintsData&amp;);
</ins><span class="cx"> 
</span><del>-    virtual ~MediaConstraintsImpl();
</del><ins>+    MediaConstraintsImpl() = default;
+    virtual ~MediaConstraintsImpl() = default;
</ins><span class="cx"> 
</span><del>-    const MediaTrackConstraintSetMap&amp; mandatoryConstraints() const final { return m_mandatoryConstraints; }
-    const Vector&lt;MediaTrackConstraintSetMap&gt;&amp; advancedConstraints() const final { return m_advancedConstraints; }
-    bool isValid() const final { return m_isValid; }
</del><ins>+    const MediaTrackConstraintSetMap&amp; mandatoryConstraints() const final { return m_data.mandatoryConstraints; }
+    const Vector&lt;MediaTrackConstraintSetMap&gt;&amp; advancedConstraints() const final { return m_data.advancedConstraints; }
+    bool isValid() const final { return m_data.isValid; }
+    const MediaConstraintsData&amp; data() const { return m_data; }
</ins><span class="cx"> 
</span><span class="cx"> private:
</span><del>-    MediaConstraintsImpl() { }
</del><span class="cx">     MediaConstraintsImpl(MediaTrackConstraintSetMap&amp;&amp; mandatoryConstraints, Vector&lt;MediaTrackConstraintSetMap&gt;&amp;&amp; advancedConstraints, bool isValid)
</span><del>-        : m_mandatoryConstraints(WTFMove(mandatoryConstraints))
-        , m_advancedConstraints(WTFMove(advancedConstraints))
-        , m_isValid(isValid)
</del><ins>+        : m_data({ WTFMove(mandatoryConstraints), WTFMove(advancedConstraints), isValid })
</ins><span class="cx">     {
</span><span class="cx">     }
</span><ins>+    explicit MediaConstraintsImpl(const MediaConstraintsData&amp; data)
+        : m_data(data)
+    {
+    }
</ins><span class="cx"> 
</span><del>-    MediaTrackConstraintSetMap m_mandatoryConstraints;
-    Vector&lt;MediaTrackConstraintSetMap&gt; m_advancedConstraints;
-    bool m_isValid;
</del><ins>+    MediaConstraintsData m_data;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesmediastreamMediaDevicesEnumerationRequestcpp"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/Modules/mediastream/MediaDevicesEnumerationRequest.cpp (0 => 207463)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/mediastream/MediaDevicesEnumerationRequest.cpp                                (rev 0)
+++ trunk/Source/WebCore/Modules/mediastream/MediaDevicesEnumerationRequest.cpp        2016-10-18 14:53:06 UTC (rev 207463)
</span><span class="lines">@@ -0,0 +1,114 @@
</span><ins>+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE, INC. ``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;MediaDevicesEnumerationRequest.h&quot;
+
+#if ENABLE(MEDIA_STREAM)
+
+#include &quot;CaptureDevice.h&quot;
+#include &quot;Document.h&quot;
+#include &quot;ExceptionCode.h&quot;
+#include &quot;Frame.h&quot;
+#include &quot;MainFrame.h&quot;
+#include &quot;SecurityOrigin.h&quot;
+#include &quot;UserMediaController.h&quot;
+
+namespace WebCore {
+
+Ref&lt;MediaDevicesEnumerationRequest&gt; MediaDevicesEnumerationRequest::create(Document&amp; document, CompletionHandler&amp;&amp; completionHandler)
+{
+    return adoptRef(*new MediaDevicesEnumerationRequest(document, WTFMove(completionHandler)));
+}
+
+MediaDevicesEnumerationRequest::MediaDevicesEnumerationRequest(ScriptExecutionContext&amp; context, CompletionHandler&amp;&amp; completionHandler)
+    : ContextDestructionObserver(&amp;context)
+    , m_completionHandler(WTFMove(completionHandler))
+{
+}
+
+MediaDevicesEnumerationRequest::~MediaDevicesEnumerationRequest()
+{
+}
+
+SecurityOrigin* MediaDevicesEnumerationRequest::userMediaDocumentOrigin() const
+{
+    if (!scriptExecutionContext())
+        return nullptr;
+
+    return scriptExecutionContext()-&gt;securityOrigin();
+}
+
+SecurityOrigin* MediaDevicesEnumerationRequest::topLevelDocumentOrigin() const
+{
+    if (!scriptExecutionContext())
+        return nullptr;
+
+    if (Frame* frame = downcast&lt;Document&gt;(*scriptExecutionContext()).frame()) {
+        if (frame-&gt;isMainFrame())
+            return nullptr;
+    }
+
+    return scriptExecutionContext()-&gt;topOrigin();
+}
+
+void MediaDevicesEnumerationRequest::contextDestroyed()
+{
+    cancel();
+    ContextDestructionObserver::contextDestroyed();
+}
+
+void MediaDevicesEnumerationRequest::start()
+{
+    ASSERT(scriptExecutionContext());
+
+    auto&amp; document = downcast&lt;Document&gt;(*scriptExecutionContext());
+    auto* controller = UserMediaController::from(document.page());
+    if (!controller)
+        return;
+
+    controller-&gt;enumerateMediaDevices(*this);
+}
+
+void MediaDevicesEnumerationRequest::cancel()
+{
+    m_completionHandler = nullptr;
+}
+
+void MediaDevicesEnumerationRequest::setDeviceInfo(const Vector&lt;CaptureDevice&gt;&amp; deviceList, const String&amp; deviceIdentifierHashSalt, bool originHasPersistentAccess)
+{
+    m_deviceList = deviceList;
+    m_deviceIdentifierHashSalt = deviceIdentifierHashSalt;
+    m_originHasPersistentAccess = originHasPersistentAccess;
+
+    if (m_completionHandler)
+        m_completionHandler(m_deviceList, m_deviceIdentifierHashSalt, m_originHasPersistentAccess);
+    m_completionHandler = nullptr;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(MEDIA_STREAM)
</ins></span></pre></div>
<a id="trunkSourceWebCoreModulesmediastreamMediaDevicesEnumerationRequesth"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/Modules/mediastream/MediaDevicesEnumerationRequest.h (0 => 207463)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/mediastream/MediaDevicesEnumerationRequest.h                                (rev 0)
+++ trunk/Source/WebCore/Modules/mediastream/MediaDevicesEnumerationRequest.h        2016-10-18 14:53:06 UTC (rev 207463)
</span><span class="lines">@@ -0,0 +1,71 @@
</span><ins>+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE, INC. ``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.
+ *
+ */
+
+#pragma once
+
+#if ENABLE(MEDIA_STREAM)
+
+#include &quot;ActiveDOMObject.h&quot;
+#include &lt;functional&gt;
+#include &lt;wtf/text/WTFString.h&gt;
+
+namespace WebCore {
+
+class CaptureDevice;
+class Document;
+class SecurityOrigin;
+
+class MediaDevicesEnumerationRequest final : public ContextDestructionObserver, public RefCounted&lt;MediaDevicesEnumerationRequest&gt; {
+public:
+    using CompletionHandler = std::function&lt;void(const Vector&lt;CaptureDevice&gt;&amp;, const String&amp; deviceIdentifierHashSalt, bool originHasPersistentAccess)&gt;;
+
+    static Ref&lt;MediaDevicesEnumerationRequest&gt; create(Document&amp;, CompletionHandler&amp;&amp;);
+
+    virtual ~MediaDevicesEnumerationRequest();
+
+    void start();
+    void cancel();
+
+    WEBCORE_EXPORT void setDeviceInfo(const Vector&lt;CaptureDevice&gt;&amp;, const String&amp; deviceIdentifierHashSalt, bool originHasPersistentAccess);
+
+    WEBCORE_EXPORT SecurityOrigin* userMediaDocumentOrigin() const;
+    WEBCORE_EXPORT SecurityOrigin* topLevelDocumentOrigin() const;
+
+private:
+    MediaDevicesEnumerationRequest(ScriptExecutionContext&amp;, CompletionHandler&amp;&amp;);
+
+    // ContextDestructionObserver
+    void contextDestroyed() final;
+
+    CompletionHandler m_completionHandler;
+    Vector&lt;CaptureDevice&gt; m_deviceList;
+    String m_deviceIdentifierHashSalt;
+    bool m_originHasPersistentAccess { false };
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(MEDIA_STREAM)
</ins></span></pre></div>
<a id="trunkSourceWebCoreModulesmediastreamMediaDevicesRequestcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/mediastream/MediaDevicesRequest.cpp (207462 => 207463)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/mediastream/MediaDevicesRequest.cpp        2016-10-18 13:15:40 UTC (rev 207462)
+++ trunk/Source/WebCore/Modules/mediastream/MediaDevicesRequest.cpp        2016-10-18 14:53:06 UTC (rev 207463)
</span><span class="lines">@@ -34,7 +34,7 @@
</span><span class="cx"> #include &quot;ExceptionCode.h&quot;
</span><span class="cx"> #include &quot;Frame.h&quot;
</span><span class="cx"> #include &quot;JSMediaDeviceInfo.h&quot;
</span><del>-#include &quot;RealtimeMediaSourceCenter.h&quot;
</del><ins>+#include &quot;MediaDevicesEnumerationRequest.h&quot;
</ins><span class="cx"> #include &quot;SecurityOrigin.h&quot;
</span><span class="cx"> #include &quot;UserMediaController.h&quot;
</span><span class="cx"> #include &lt;wtf/MainThread.h&gt;
</span><span class="lines">@@ -55,8 +55,8 @@
</span><span class="cx"> 
</span><span class="cx"> MediaDevicesRequest::~MediaDevicesRequest()
</span><span class="cx"> {
</span><del>-    if (m_permissionCheck)
-        m_permissionCheck-&gt;setClient(nullptr);
</del><ins>+    if (m_enumerationRequest)
+        m_enumerationRequest-&gt;cancel();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> SecurityOrigin* MediaDevicesRequest::securityOrigin() const
</span><span class="lines">@@ -69,19 +69,52 @@
</span><span class="cx"> 
</span><span class="cx"> void MediaDevicesRequest::contextDestroyed()
</span><span class="cx"> {
</span><ins>+    if (m_enumerationRequest) {
+        m_enumerationRequest-&gt;cancel();
+        m_enumerationRequest = nullptr;
+    }
</ins><span class="cx">     ContextDestructionObserver::contextDestroyed();
</span><del>-    if (m_permissionCheck) {
-        m_permissionCheck-&gt;setClient(nullptr);
-        m_permissionCheck = nullptr;
-    }
-    m_protector = nullptr;
</del><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void MediaDevicesRequest::start()
</span><span class="cx"> {
</span><del>-    m_protector = this;
-    m_permissionCheck = UserMediaPermissionCheck::create(*downcast&lt;Document&gt;(scriptExecutionContext()), *this);
-    m_permissionCheck-&gt;start();
</del><ins>+    RefPtr&lt;MediaDevicesRequest&gt; protectedThis = this;
+    auto completion = [this, protectedThis = WTFMove(protectedThis)] (const Vector&lt;CaptureDevice&gt;&amp; captureDevices, const String&amp; deviceIdentifierHashSalt, bool originHasPersistentAccess) mutable {
+
+        m_enumerationRequest = nullptr;
+
+        if (!scriptExecutionContext())
+            return;
+
+        Document&amp; document = downcast&lt;Document&gt;(*scriptExecutionContext());
+        UserMediaController* controller = UserMediaController::from(document.page());
+        if (!controller)
+            return;
+
+        m_idHashSalt = deviceIdentifierHashSalt;
+
+        Vector&lt;RefPtr&lt;MediaDeviceInfo&gt;&gt; devices;
+        for (auto&amp; deviceInfo : captureDevices) {
+            auto label = emptyString();
+            if (originHasPersistentAccess || document.hasHadActiveMediaStreamTrack())
+                label = deviceInfo.label();
+
+            auto id = hashID(deviceInfo.persistentId());
+            if (id.isEmpty())
+                continue;
+
+            auto groupId = hashID(deviceInfo.groupId());
+            auto deviceType = deviceInfo.kind() == CaptureDevice::SourceKind::Audio ? MediaDeviceInfo::Kind::Audioinput : MediaDeviceInfo::Kind::Videoinput;
+            devices.append(MediaDeviceInfo::create(scriptExecutionContext(), label, id, groupId, deviceType));
+        }
+
+        callOnMainThread([protectedThis = makeRef(*this), devices = WTFMove(devices)]() mutable {
+            protectedThis-&gt;m_promise.resolve(devices);
+        });
+    };
+
+    m_enumerationRequest = MediaDevicesEnumerationRequest::create(*downcast&lt;Document&gt;(scriptExecutionContext()), WTFMove(completion));
+    m_enumerationRequest-&gt;start();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> static void hashString(SHA1&amp; sha1, const String&amp; string)
</span><span class="lines">@@ -116,48 +149,6 @@
</span><span class="cx">     return SHA1::hexDigest(digest).data();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void MediaDevicesRequest::didCompletePermissionCheck(const String&amp; salt, bool canAccess)
-{
-    m_permissionCheck-&gt;setClient(nullptr);
-    m_permissionCheck = nullptr;
-
-    m_idHashSalt = salt;
-    m_havePersistentPermission = canAccess;
-
-    if (!scriptExecutionContext()) {
-        m_protector = nullptr;
-        return;
-    }
-
-    Document&amp; document = downcast&lt;Document&gt;(*scriptExecutionContext());
-    UserMediaController* controller = UserMediaController::from(document.page());
-    if (!controller) {
-        m_protector = nullptr;
-        return;
-    }
-
-    Vector&lt;RefPtr&lt;MediaDeviceInfo&gt;&gt; devices;
-    auto captureDevices = RealtimeMediaSourceCenter::singleton().getMediaStreamDevices();
-    for (auto&amp; deviceInfo : captureDevices) {
-        auto label = emptyString();
-        if (m_havePersistentPermission || document.hasHadActiveMediaStreamTrack())
-            label = deviceInfo.label();
-
-        auto id = hashID(deviceInfo.persistentId());
-        if (id.isEmpty())
-            continue;
-
-        auto groupId = hashID(deviceInfo.groupId());
-        auto deviceType = deviceInfo.kind() == CaptureDevice::SourceKind::Audio ? MediaDeviceInfo::Kind::Audioinput : MediaDeviceInfo::Kind::Videoinput;
-        devices.append(MediaDeviceInfo::create(scriptExecutionContext(), label, id, groupId, deviceType));
-    }
-
-    callOnMainThread([protectedThis = makeRef(*this), devices = WTFMove(devices)]() mutable {
-        protectedThis-&gt;m_promise.resolve(devices);
-    });
-    m_protector = nullptr;
-}
-
</del><span class="cx"> } // namespace WebCore
</span><span class="cx"> 
</span><span class="cx"> #endif // ENABLE(MEDIA_STREAM)
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesmediastreamMediaDevicesRequesth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/mediastream/MediaDevicesRequest.h (207462 => 207463)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/mediastream/MediaDevicesRequest.h        2016-10-18 13:15:40 UTC (rev 207462)
+++ trunk/Source/WebCore/Modules/mediastream/MediaDevicesRequest.h        2016-10-18 14:53:06 UTC (rev 207463)
</span><span class="lines">@@ -31,8 +31,6 @@
</span><span class="cx"> 
</span><span class="cx"> #include &quot;ActiveDOMObject.h&quot;
</span><span class="cx"> #include &quot;MediaDevices.h&quot;
</span><del>-#include &quot;MediaStreamCreationClient.h&quot;
-#include &quot;UserMediaPermissionCheck.h&quot;
</del><span class="cx"> #include &lt;wtf/RefCounted.h&gt;
</span><span class="cx"> #include &lt;wtf/text/WTFString.h&gt;
</span><span class="cx"> 
</span><span class="lines">@@ -40,11 +38,12 @@
</span><span class="cx"> 
</span><span class="cx"> class Document;
</span><span class="cx"> class Frame;
</span><ins>+class MediaDevicesEnumerationRequest;
</ins><span class="cx"> class SecurityOrigin;
</span><span class="cx"> 
</span><span class="cx"> typedef int ExceptionCode;
</span><span class="cx"> 
</span><del>-class MediaDevicesRequest : public RefCounted&lt;MediaDevicesRequest&gt;, public UserMediaPermissionCheckClient, public ContextDestructionObserver {
</del><ins>+class MediaDevicesRequest : public RefCounted&lt;MediaDevicesRequest&gt;, private 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">@@ -60,17 +59,13 @@
</span><span class="cx">     // ContextDestructionObserver
</span><span class="cx">     void contextDestroyed() final;
</span><span class="cx"> 
</span><del>-    // UserMediaPermissionCheckClient
-    void didCompletePermissionCheck(const String&amp;, bool) final;
-
</del><span class="cx">     String hashID(const String&amp;);
</span><span class="cx"> 
</span><span class="cx">     MediaDevices::EnumerateDevicesPromise m_promise;
</span><span class="cx">     RefPtr&lt;MediaDevicesRequest&gt; m_protector;
</span><del>-    RefPtr&lt;UserMediaPermissionCheck&gt; m_permissionCheck;
</del><ins>+    RefPtr&lt;MediaDevicesEnumerationRequest&gt; m_enumerationRequest;
</ins><span class="cx"> 
</span><span class="cx">     String m_idHashSalt;
</span><del>-    bool m_havePersistentPermission { false };
</del><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesmediastreamUserMediaClienth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/mediastream/UserMediaClient.h (207462 => 207463)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/mediastream/UserMediaClient.h        2016-10-18 13:15:40 UTC (rev 207462)
+++ trunk/Source/WebCore/Modules/mediastream/UserMediaClient.h        2016-10-18 14:53:06 UTC (rev 207463)
</span><span class="lines">@@ -1,5 +1,6 @@
</span><span class="cx"> /*
</span><span class="cx">  * Copyright (C) 2011 Ericsson AB. All rights reserved.
</span><ins>+ * Copyright (C) 2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -33,10 +34,16 @@
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(MEDIA_STREAM)
</span><span class="cx"> 
</span><ins>+#include &lt;functional&gt;
+#include &lt;wtf/Vector.h&gt;
+#include &lt;wtf/text/WTFString.h&gt;
+
</ins><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><ins>+class MediaDevicesEnumerationRequest;
+class MediaConstraints;
</ins><span class="cx"> class Page;
</span><del>-class UserMediaPermissionCheck;
</del><ins>+class RealtimeMediaSource;
</ins><span class="cx"> class UserMediaRequest;
</span><span class="cx"> 
</span><span class="cx"> class UserMediaClient {
</span><span class="lines">@@ -46,8 +53,8 @@
</span><span class="cx">     virtual void requestUserMediaAccess(UserMediaRequest&amp;) = 0;
</span><span class="cx">     virtual void cancelUserMediaAccessRequest(UserMediaRequest&amp;) = 0;
</span><span class="cx"> 
</span><del>-    virtual void checkUserMediaPermission(UserMediaPermissionCheck&amp;) = 0;
-    virtual void cancelUserMediaPermissionCheck(UserMediaPermissionCheck&amp;) = 0;
</del><ins>+    virtual void enumerateMediaDevices(MediaDevicesEnumerationRequest&amp;) = 0;
+    virtual void cancelMediaDevicesEnumerationRequest(MediaDevicesEnumerationRequest&amp;) = 0;
</ins><span class="cx"> 
</span><span class="cx"> protected:
</span><span class="cx">     virtual ~UserMediaClient() { }
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesmediastreamUserMediaControllerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/mediastream/UserMediaController.h (207462 => 207463)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/mediastream/UserMediaController.h        2016-10-18 13:15:40 UTC (rev 207462)
+++ trunk/Source/WebCore/Modules/mediastream/UserMediaController.h        2016-10-18 14:53:06 UTC (rev 207463)
</span><span class="lines">@@ -1,5 +1,6 @@
</span><span class="cx"> /*
</span><span class="cx">  * Copyright (C) 2012 Google Inc. All rights reserved.
</span><ins>+ * Copyright (C) 2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -29,7 +30,6 @@
</span><span class="cx"> 
</span><span class="cx"> #include &quot;Page.h&quot;
</span><span class="cx"> #include &quot;UserMediaClient.h&quot;
</span><del>-#include &quot;UserMediaPermissionCheck.h&quot;
</del><span class="cx"> #include &quot;UserMediaRequest.h&quot;
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="lines">@@ -44,8 +44,8 @@
</span><span class="cx">     void requestUserMediaAccess(UserMediaRequest&amp;);
</span><span class="cx">     void cancelUserMediaAccessRequest(UserMediaRequest&amp;);
</span><span class="cx"> 
</span><del>-    void checkUserMediaPermission(UserMediaPermissionCheck&amp;);
-    void cancelUserMediaPermissionCheck(UserMediaPermissionCheck&amp;);
</del><ins>+    void enumerateMediaDevices(MediaDevicesEnumerationRequest&amp;);
+    void cancelMediaDevicesEnumerationRequest(MediaDevicesEnumerationRequest&amp;);
</ins><span class="cx"> 
</span><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="lines">@@ -64,14 +64,14 @@
</span><span class="cx">     m_client-&gt;cancelUserMediaAccessRequest(request);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-inline void UserMediaController::checkUserMediaPermission(UserMediaPermissionCheck&amp; request)
</del><ins>+inline void UserMediaController::enumerateMediaDevices(MediaDevicesEnumerationRequest&amp; request)
</ins><span class="cx"> {
</span><del>-    m_client-&gt;checkUserMediaPermission(request);
</del><ins>+    m_client-&gt;enumerateMediaDevices(request);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-inline void UserMediaController::cancelUserMediaPermissionCheck(UserMediaPermissionCheck&amp; request)
</del><ins>+inline void UserMediaController::cancelMediaDevicesEnumerationRequest(MediaDevicesEnumerationRequest&amp; request)
</ins><span class="cx"> {
</span><del>-    m_client-&gt;cancelUserMediaPermissionCheck(request);
</del><ins>+    m_client-&gt;cancelMediaDevicesEnumerationRequest(request);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesmediastreamUserMediaPermissionCheckcpp"></a>
<div class="delfile"><h4>Deleted: trunk/Source/WebCore/Modules/mediastream/UserMediaPermissionCheck.cpp (207462 => 207463)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/mediastream/UserMediaPermissionCheck.cpp        2016-10-18 13:15:40 UTC (rev 207462)
+++ trunk/Source/WebCore/Modules/mediastream/UserMediaPermissionCheck.cpp        2016-10-18 14:53:06 UTC (rev 207463)
</span><span class="lines">@@ -1,107 +0,0 @@
</span><del>-/*
- * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * 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;MainFrame.h&quot;
-#include &quot;RealtimeMediaSourceCenter.h&quot;
-#include &quot;SecurityOrigin.h&quot;
-#include &quot;UserMediaController.h&quot;
-
-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::userMediaDocumentOrigin() const
-{
-    if (m_scriptExecutionContext)
-        return m_scriptExecutionContext-&gt;securityOrigin();
-
-    return nullptr;
-}
-
-SecurityOrigin* UserMediaPermissionCheck::topLevelDocumentOrigin() const
-{
-    if (!m_scriptExecutionContext)
-        return nullptr;
-
-    if (Frame* frame = downcast&lt;Document&gt;(*scriptExecutionContext()).frame()) {
-        if (frame-&gt;isMainFrame())
-            return nullptr;
-    }
-
-    return m_scriptExecutionContext-&gt;topOrigin();
-}
-
-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::setUserMediaAccessInfo(const String&amp; mediaDeviceIdentifierHashSalt, bool hasPersistentPermission)
-{
-    m_hasPersistentPermission = hasPersistentPermission;
-    m_mediaDeviceIdentifierHashSalt = mediaDeviceIdentifierHashSalt;
-
-    if (m_client)
-        m_client-&gt;didCompletePermissionCheck(m_mediaDeviceIdentifierHashSalt, m_hasPersistentPermission);
-}
-
-} // namespace WebCore
-
-#endif // ENABLE(MEDIA_STREAM)
</del></span></pre></div>
<a id="trunkSourceWebCoreModulesmediastreamUserMediaPermissionCheckh"></a>
<div class="delfile"><h4>Deleted: trunk/Source/WebCore/Modules/mediastream/UserMediaPermissionCheck.h (207462 => 207463)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/mediastream/UserMediaPermissionCheck.h        2016-10-18 13:15:40 UTC (rev 207462)
+++ trunk/Source/WebCore/Modules/mediastream/UserMediaPermissionCheck.h        2016-10-18 14:53:06 UTC (rev 207463)
</span><span class="lines">@@ -1,79 +0,0 @@
</span><del>-/*
- * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * 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 &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 didCompletePermissionCheck(const String&amp;, 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 SecurityOrigin* userMediaDocumentOrigin() const;
-    WEBCORE_EXPORT SecurityOrigin* topLevelDocumentOrigin() const;
-
-    WEBCORE_EXPORT void setUserMediaAccessInfo(const String&amp;, bool);
-
-    WEBCORE_EXPORT String mediaDeviceIdentifierHashSalt() const { return m_mediaDeviceIdentifierHashSalt; }
-
-private:
-    UserMediaPermissionCheck(ScriptExecutionContext&amp;, UserMediaPermissionCheckClient&amp;);
-
-    // ContextDestructionObserver
-    void contextDestroyed() final;
-
-    UserMediaPermissionCheckClient* m_client;
-    String m_mediaDeviceIdentifierHashSalt;
-    bool m_hasPersistentPermission { false };
-};
-
-} // namespace WebCore
-
-#endif // ENABLE(MEDIA_STREAM)
-
-#endif // UserMediaPermissionCheck_h
</del></span></pre></div>
<a id="trunkSourceWebCoreModulesmediastreamUserMediaRequestcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/mediastream/UserMediaRequest.cpp (207462 => 207463)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/mediastream/UserMediaRequest.cpp        2016-10-18 13:15:40 UTC (rev 207462)
+++ trunk/Source/WebCore/Modules/mediastream/UserMediaRequest.cpp        2016-10-18 14:53:06 UTC (rev 207463)
</span><span class="lines">@@ -37,16 +37,15 @@
</span><span class="cx"> 
</span><span class="cx"> #include &quot;UserMediaRequest.h&quot;
</span><span class="cx"> 
</span><del>-#include &quot;Dictionary.h&quot;
</del><span class="cx"> #include &quot;Document.h&quot;
</span><span class="cx"> #include &quot;ExceptionCode.h&quot;
</span><span class="cx"> #include &quot;Frame.h&quot;
</span><del>-#include &quot;JSMediaDeviceInfo.h&quot;
</del><span class="cx"> #include &quot;JSMediaStream.h&quot;
</span><ins>+#include &quot;JSOverconstrainedError.h&quot;
</ins><span class="cx"> #include &quot;MainFrame.h&quot;
</span><del>-#include &quot;MediaConstraintsImpl.h&quot;
</del><span class="cx"> #include &quot;MediaStream.h&quot;
</span><span class="cx"> #include &quot;MediaStreamPrivate.h&quot;
</span><ins>+#include &quot;OverconstrainedError.h&quot;
</ins><span class="cx"> #include &quot;RealtimeMediaSourceCenter.h&quot;
</span><span class="cx"> #include &quot;SecurityOrigin.h&quot;
</span><span class="cx"> #include &quot;UserMediaController.h&quot;
</span><span class="lines">@@ -71,7 +70,7 @@
</span><span class="cx">     request-&gt;start();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-UserMediaRequest::UserMediaRequest(ScriptExecutionContext* context, UserMediaController* controller, Ref&lt;MediaConstraints&gt;&amp;&amp; audioConstraints, Ref&lt;MediaConstraints&gt;&amp;&amp; videoConstraints, MediaDevices::Promise&amp;&amp; promise)
</del><ins>+UserMediaRequest::UserMediaRequest(ScriptExecutionContext* context, UserMediaController* controller, Ref&lt;MediaConstraintsImpl&gt;&amp;&amp; audioConstraints, Ref&lt;MediaConstraintsImpl&gt;&amp;&amp; videoConstraints, MediaDevices::Promise&amp;&amp; promise)
</ins><span class="cx">     : ContextDestructionObserver(context)
</span><span class="cx">     , m_audioConstraints(WTFMove(audioConstraints))
</span><span class="cx">     , m_videoConstraints(WTFMove(videoConstraints))
</span><span class="lines">@@ -102,86 +101,79 @@
</span><span class="cx"> 
</span><span class="cx"> void UserMediaRequest::start()
</span><span class="cx"> {
</span><del>-    // 1 - make sure the system is capable of supporting the audio and video constraints. We don't want to ask for
-    // user permission if the constraints can not be suported.
-    RealtimeMediaSourceCenter::singleton().validateRequestConstraints(this, m_audioConstraints, m_videoConstraints);
</del><ins>+    if (m_controller)
+        m_controller-&gt;requestUserMediaAccess(*this);
+    else
+        deny(MediaAccessDenialReason::OtherFailure, emptyString());
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-void UserMediaRequest::constraintsValidated(const Vector&lt;RefPtr&lt;RealtimeMediaSource&gt;&gt;&amp; audioTracks, const Vector&lt;RefPtr&lt;RealtimeMediaSource&gt;&gt;&amp; videoTracks)
</del><ins>+void UserMediaRequest::allow(const String&amp; audioDeviceUID, const String&amp; videoDeviceUID)
</ins><span class="cx"> {
</span><del>-    for (auto&amp; audioTrack : audioTracks)
-        m_audioDeviceUIDs.append(audioTrack-&gt;persistentID());
-    for (auto&amp; videoTrack : videoTracks)
-        m_videoDeviceUIDs.append(videoTrack-&gt;persistentID());
-
-    callOnMainThread([protectedThis = makeRef(*this)]() mutable {
-        // 2 - The constraints are valid, ask the user for access to media.
-        if (UserMediaController* controller = protectedThis-&gt;m_controller)
-            controller-&gt;requestUserMediaAccess(protectedThis.get());
-    });
-}
-
-void UserMediaRequest::userMediaAccessGranted(const String&amp; audioDeviceUID, const String&amp; videoDeviceUID)
-{
</del><ins>+    m_allowedAudioDeviceUID = audioDeviceUID;
</ins><span class="cx">     m_allowedVideoDeviceUID = videoDeviceUID;
</span><del>-    m_audioDeviceUIDAllowed = audioDeviceUID;
</del><span class="cx"> 
</span><del>-    callOnMainThread([protectedThis = makeRef(*this), audioDeviceUID, videoDeviceUID]() mutable {
-        // 3 - the user granted access, ask platform to create the media stream descriptors.
-        RealtimeMediaSourceCenter::singleton().createMediaStream(protectedThis.ptr(), audioDeviceUID, videoDeviceUID);
-    });
-}
</del><ins>+    RefPtr&lt;UserMediaRequest&gt; protectedThis = this;
+    RealtimeMediaSourceCenter::NewMediaStreamHandler callback = [this, protectedThis = WTFMove(protectedThis)](RefPtr&lt;MediaStreamPrivate&gt;&amp;&amp; privateStream) mutable {
+        if (!m_scriptExecutionContext)
+            return;
</ins><span class="cx"> 
</span><del>-void UserMediaRequest::userMediaAccessDenied()
-{
-    failedToCreateStreamWithPermissionError();
-}
</del><ins>+        if (!privateStream) {
+            deny(MediaAccessDenialReason::HardwareError, emptyString());
+            return;
+        }
</ins><span class="cx"> 
</span><del>-void UserMediaRequest::constraintsInvalid(const String&amp; constraintName)
-{
-    failedToCreateStreamWithConstraintsError(constraintName);
-}
</del><ins>+        auto stream = MediaStream::create(*m_scriptExecutionContext, WTFMove(privateStream));
+        if (stream-&gt;getTracks().isEmpty()) {
+            deny(MediaAccessDenialReason::HardwareError, emptyString());
+            return;
+        }
</ins><span class="cx"> 
</span><del>-void UserMediaRequest::didCreateStream(RefPtr&lt;MediaStreamPrivate&gt;&amp;&amp; privateStream)
-{
-    if (!m_scriptExecutionContext)
-        return;
</del><ins>+        for (auto&amp; track : stream-&gt;getAudioTracks()) {
+            track-&gt;applyConstraints(m_audioConstraints);
+            track-&gt;source().startProducingData();
+        }
</ins><span class="cx"> 
</span><del>-    // 4 - Create the MediaStream and pass it to the success callback.
-    Ref&lt;MediaStream&gt; stream = MediaStream::create(*m_scriptExecutionContext, WTFMove(privateStream));
</del><ins>+        for (auto&amp; track : stream-&gt;getVideoTracks()) {
+            track-&gt;applyConstraints(m_videoConstraints);
+            track-&gt;source().startProducingData();
+        }
+        
+        m_promise.resolve(stream);
+    };
</ins><span class="cx"> 
</span><del>-    for (auto&amp; track : stream-&gt;getAudioTracks()) {
-        track-&gt;applyConstraints(m_audioConstraints);
-        track-&gt;source().startProducingData();
-    }
-
-    for (auto&amp; track : stream-&gt;getVideoTracks()) {
-        track-&gt;applyConstraints(m_videoConstraints);
-        track-&gt;source().startProducingData();
-    }
-
-    m_promise.resolve(stream);
</del><ins>+    RealtimeMediaSourceCenter::singleton().createMediaStream(WTFMove(callback), m_allowedAudioDeviceUID, m_allowedVideoDeviceUID);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-void UserMediaRequest::failedToCreateStreamWithConstraintsError(const String&amp; constraintName)
</del><ins>+void UserMediaRequest::deny(MediaAccessDenialReason reason, const String&amp; invalidConstraint)
</ins><span class="cx"> {
</span><del>-    UNUSED_PARAM(constraintName);
-    ASSERT(!constraintName.isEmpty());
</del><span class="cx">     if (!m_scriptExecutionContext)
</span><span class="cx">         return;
</span><span class="cx"> 
</span><del>-    // FIXME: The promise should be rejected with an OverconstrainedError, https://bugs.webkit.org/show_bug.cgi?id=157839.
-    m_promise.reject(DataError);
</del><ins>+    switch (reason) {
+    case MediaAccessDenialReason::NoConstraints:
+        m_promise.reject(TypeError);
+        break;
+    case MediaAccessDenialReason::UserMediaDisabled:
+        m_promise.reject(SECURITY_ERR);
+        break;
+    case MediaAccessDenialReason::NoCaptureDevices:
+        m_promise.reject(NOT_FOUND_ERR);
+        break;
+    case MediaAccessDenialReason::InvalidConstraint:
+        m_promise.reject(OverconstrainedError::create(invalidConstraint, ASCIILiteral(&quot;Invalid constraint&quot;)).get());
+        break;
+    case MediaAccessDenialReason::HardwareError:
+        m_promise.reject(NotReadableError);
+        break;
+    case MediaAccessDenialReason::OtherFailure:
+        m_promise.reject(ABORT_ERR);
+        break;
+    case MediaAccessDenialReason::PermissionDenied:
+        m_promise.reject(NotAllowedError);
+        break;
+    }
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-void UserMediaRequest::failedToCreateStreamWithPermissionError()
-{
-    if (!m_scriptExecutionContext)
-        return;
-
-    m_promise.reject(NotAllowedError);
-}
-
</del><span class="cx"> void UserMediaRequest::contextDestroyed()
</span><span class="cx"> {
</span><span class="cx">     Ref&lt;UserMediaRequest&gt; protectedThis(*this);
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesmediastreamUserMediaRequesth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/mediastream/UserMediaRequest.h (207462 => 207463)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/mediastream/UserMediaRequest.h        2016-10-18 13:15:40 UTC (rev 207462)
+++ trunk/Source/WebCore/Modules/mediastream/UserMediaRequest.h        2016-10-18 14:53:06 UTC (rev 207463)
</span><span class="lines">@@ -36,8 +36,9 @@
</span><span class="cx"> #if ENABLE(MEDIA_STREAM)
</span><span class="cx"> 
</span><span class="cx"> #include &quot;ActiveDOMObject.h&quot;
</span><ins>+#include &quot;Document.h&quot;
+#include &quot;MediaConstraintsImpl.h&quot;
</ins><span class="cx"> #include &quot;MediaDevices.h&quot;
</span><del>-#include &quot;MediaStreamCreationClient.h&quot;
</del><span class="cx"> #include &lt;wtf/RefCounted.h&gt;
</span><span class="cx"> #include &lt;wtf/text/WTFString.h&gt;
</span><span class="cx"> 
</span><span class="lines">@@ -53,49 +54,51 @@
</span><span class="cx"> 
</span><span class="cx"> typedef int ExceptionCode;
</span><span class="cx"> 
</span><del>-class UserMediaRequest : public MediaStreamCreationClient, public ContextDestructionObserver {
</del><ins>+class UserMediaRequest : public RefCounted&lt;UserMediaRequest&gt;, private ContextDestructionObserver {
</ins><span class="cx"> public:
</span><span class="cx">     static void start(Document*, Ref&lt;MediaConstraintsImpl&gt;&amp;&amp; audioConstraints, Ref&lt;MediaConstraintsImpl&gt;&amp;&amp; videoConstraints, MediaDevices::Promise&amp;&amp;, ExceptionCode&amp;);
</span><span class="cx"> 
</span><span class="cx">     ~UserMediaRequest();
</span><span class="cx"> 
</span><del>-    WEBCORE_EXPORT SecurityOrigin* userMediaDocumentOrigin() const;
-    WEBCORE_EXPORT SecurityOrigin* topLevelDocumentOrigin() const;
-
</del><span class="cx">     void start();
</span><del>-    WEBCORE_EXPORT void userMediaAccessGranted(const String&amp; audioDeviceUID, const String&amp; videoDeviceUID);
-    WEBCORE_EXPORT void userMediaAccessDenied();
</del><span class="cx"> 
</span><ins>+    WEBCORE_EXPORT void setAllowedMediaDeviceUIDs(const String&amp; audioDeviceUID, const String&amp; videoDeviceUID);
+    WEBCORE_EXPORT void allow(const String&amp; audioDeviceUID, const String&amp; videoDeviceUID);
+
+    enum MediaAccessDenialReason { NoConstraints, UserMediaDisabled, NoCaptureDevices, InvalidConstraint, HardwareError, PermissionDenied, OtherFailure };
+    WEBCORE_EXPORT void deny(MediaAccessDenialReason, const String&amp; invalidConstraint);
+
</ins><span class="cx">     const Vector&lt;String&gt;&amp; audioDeviceUIDs() const { return m_audioDeviceUIDs; }
</span><span class="cx">     const Vector&lt;String&gt;&amp; videoDeviceUIDs() const { return m_videoDeviceUIDs; }
</span><span class="cx"> 
</span><del>-    const String&amp; allowedAudioDeviceUID() const { return m_audioDeviceUIDAllowed; }
</del><ins>+    const MediaConstraintsImpl&amp; audioConstraints() const { return m_audioConstraints; }
+    const MediaConstraintsImpl&amp; videoConstraints() const { return m_videoConstraints; }
+
+    const String&amp; allowedAudioDeviceUID() const { return m_allowedAudioDeviceUID; }
</ins><span class="cx">     const String&amp; allowedVideoDeviceUID() const { return m_allowedVideoDeviceUID; }
</span><span class="cx"> 
</span><ins>+    WEBCORE_EXPORT SecurityOrigin* userMediaDocumentOrigin() const;
+    WEBCORE_EXPORT SecurityOrigin* topLevelDocumentOrigin() const;
+    WEBCORE_EXPORT Document* document() const { return downcast&lt;Document&gt;(scriptExecutionContext()); }
+
</ins><span class="cx"> private:
</span><del>-    UserMediaRequest(ScriptExecutionContext*, UserMediaController*, Ref&lt;MediaConstraints&gt;&amp;&amp; audioConstraints, Ref&lt;MediaConstraints&gt;&amp;&amp; videoConstraints, MediaDevices::Promise&amp;&amp;);
</del><ins>+    UserMediaRequest(ScriptExecutionContext*, UserMediaController*, Ref&lt;MediaConstraintsImpl&gt;&amp;&amp; audioConstraints, Ref&lt;MediaConstraintsImpl&gt;&amp;&amp; videoConstraints, MediaDevices::Promise&amp;&amp;);
</ins><span class="cx"> 
</span><del>-    // MediaStreamCreationClient
-    void constraintsValidated(const Vector&lt;RefPtr&lt;RealtimeMediaSource&gt;&gt;&amp; audioTracks, const Vector&lt;RefPtr&lt;RealtimeMediaSource&gt;&gt;&amp; videoTracks) final;
-    void constraintsInvalid(const String&amp; constraintName) final;
-    void didCreateStream(RefPtr&lt;MediaStreamPrivate&gt;&amp;&amp;) final;
-    void failedToCreateStreamWithConstraintsError(const String&amp; constraintName) final;
-    void failedToCreateStreamWithPermissionError() final;
-
</del><span class="cx">     // ContextDestructionObserver
</span><span class="cx">     void contextDestroyed() final;
</span><span class="cx">     
</span><del>-    Ref&lt;MediaConstraints&gt; m_audioConstraints;
-    Ref&lt;MediaConstraints&gt; m_videoConstraints;
</del><ins>+    Ref&lt;MediaConstraintsImpl&gt; m_audioConstraints;
+    Ref&lt;MediaConstraintsImpl&gt; m_videoConstraints;
</ins><span class="cx"> 
</span><span class="cx">     Vector&lt;String&gt; m_videoDeviceUIDs;
</span><span class="cx">     Vector&lt;String&gt; m_audioDeviceUIDs;
</span><span class="cx"> 
</span><span class="cx">     String m_allowedVideoDeviceUID;
</span><del>-    String m_audioDeviceUIDAllowed;
</del><ins>+    String m_allowedAudioDeviceUID;
</ins><span class="cx"> 
</span><span class="cx">     UserMediaController* m_controller;
</span><span class="cx">     MediaDevices::Promise m_promise;
</span><ins>+    RefPtr&lt;UserMediaRequest&gt; m_protector;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCoreWebCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (207462 => 207463)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2016-10-18 13:15:40 UTC (rev 207462)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2016-10-18 14:53:06 UTC (rev 207463)
</span><span class="lines">@@ -136,8 +136,6 @@
</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><del>-                07297FA71C1881C5003F0735 /* UserMediaPermissionCheck.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 07297FA51C1881C5003F0735 /* UserMediaPermissionCheck.cpp */; };
-                07297FA81C1881C5003F0735 /* UserMediaPermissionCheck.h in Headers */ = {isa = PBXBuildFile; fileRef = 07297FA61C1881C5003F0735 /* UserMediaPermissionCheck.h */; settings = {ATTRIBUTES = (Private, ); }; };
</del><span class="cx">                 072A70401D6E8F6200DF0AFC /* OverconstrainedErrorEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 072A703E1D6E8F6200DF0AFC /* OverconstrainedErrorEvent.h */; };
</span><span class="cx">                 072A70431D7396B300DF0AFC /* JSMediaDevicesCustom.h in Headers */ = {isa = PBXBuildFile; fileRef = 072A70421D7396B200DF0AFC /* JSMediaDevicesCustom.h */; };
</span><span class="cx">                 072AE1E5183C0741000A5988 /* PluginReplacement.h in Headers */ = {isa = PBXBuildFile; fileRef = 072AE1DF183C0741000A5988 /* PluginReplacement.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="lines">@@ -235,7 +233,6 @@
</span><span class="cx">                 078E092F17D14D1C00420AA1 /* UserMediaController.h in Headers */ = {isa = PBXBuildFile; fileRef = 07221B8F17CEC32700848E51 /* UserMediaController.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 078E093017D14D1C00420AA1 /* UserMediaRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = 07221B9117CEC32700848E51 /* UserMediaRequest.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 078E093717D16B2C00420AA1 /* MediaStreamPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 07221B9D17CF0AD400848E51 /* MediaStreamPrivate.h */; };
</span><del>-                078E093917D16B2C00420AA1 /* MediaStreamCreationClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 07221BA017CF0AD400848E51 /* MediaStreamCreationClient.h */; settings = {ATTRIBUTES = (Private, ); }; };
</del><span class="cx">                 078E093A17D16E1C00420AA1 /* MediaConstraints.h in Headers */ = {isa = PBXBuildFile; fileRef = 07221B9917CF0AD400848E51 /* MediaConstraints.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 078E093C17D16E1C00420AA1 /* RTCDataChannelHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = 07221BA217CF0AD400848E51 /* RTCDataChannelHandler.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 078E093D17D16E1C00420AA1 /* RTCDataChannelHandlerClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 07221BA317CF0AD400848E51 /* RTCDataChannelHandlerClient.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="lines">@@ -290,6 +287,8 @@
</span><span class="cx">                 07AB996B18DA3C010018771E /* RTCIceServer.h in Headers */ = {isa = PBXBuildFile; fileRef = 07AB996718DA3C010018771E /* RTCIceServer.h */; };
</span><span class="cx">                 07AB996F18DA3C740018771E /* RTCConfigurationPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 07AB996D18DA3C740018771E /* RTCConfigurationPrivate.h */; };
</span><span class="cx">                 07AB997018DA3C740018771E /* RTCIceServerPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 07AB996E18DA3C740018771E /* RTCIceServerPrivate.h */; };
</span><ins>+                07ABEF6C1D8A1C5800F21972 /* MediaDevicesEnumerationRequest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 07ABEF6B1D8A1C5800F21972 /* MediaDevicesEnumerationRequest.cpp */; };
+                07ABEF6E1D8A1C7600F21972 /* MediaDevicesEnumerationRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = 07ABEF6D1D8A1C7600F21972 /* MediaDevicesEnumerationRequest.h */; settings = {ATTRIBUTES = (Private, ); }; };
</ins><span class="cx">                 07AC47011952102100EE9723 /* ISOVTTCue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 07AC46FF1952102100EE9723 /* ISOVTTCue.cpp */; };
</span><span class="cx">                 07AC47021952102100EE9723 /* ISOVTTCue.h in Headers */ = {isa = PBXBuildFile; fileRef = 07AC47001952102100EE9723 /* ISOVTTCue.h */; };
</span><span class="cx">                 07B0113F1032242200FBDC33 /* AccessibilityMediaControls.h in Headers */ = {isa = PBXBuildFile; fileRef = 07B0113E1032242200FBDC33 /* AccessibilityMediaControls.h */; };
</span><span class="lines">@@ -299,7 +298,7 @@
</span><span class="cx">                 07B5A2DB1464320A00A81ECE /* JSTextTrackList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 07B5A2D91464320A00A81ECE /* JSTextTrackList.cpp */; };
</span><span class="cx">                 07B5A2DC1464320A00A81ECE /* JSTextTrackList.h in Headers */ = {isa = PBXBuildFile; fileRef = 07B5A2DA1464320A00A81ECE /* JSTextTrackList.h */; };
</span><span class="cx">                 07B5A30D14687D7100A81ECE /* JSTextTrackListCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 07B5A30C14687D7100A81ECE /* JSTextTrackListCustom.cpp */; };
</span><del>-                07B7116D1D899E63009F0FFB /* CaptureDevice.h in Headers */ = {isa = PBXBuildFile; fileRef = 07B7116A1D899E63009F0FFB /* CaptureDevice.h */; };
</del><ins>+                07B7116D1D899E63009F0FFB /* CaptureDevice.h in Headers */ = {isa = PBXBuildFile; fileRef = 07B7116A1D899E63009F0FFB /* CaptureDevice.h */; settings = {ATTRIBUTES = (Private, ); }; };
</ins><span class="cx">                 07B7116E1D899E63009F0FFB /* CaptureDeviceManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 07B7116B1D899E63009F0FFB /* CaptureDeviceManager.cpp */; };
</span><span class="cx">                 07B7116F1D899E63009F0FFB /* CaptureDeviceManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 07B7116C1D899E63009F0FFB /* CaptureDeviceManager.h */; };
</span><span class="cx">                 07BDD6EC1469B4C2009C9F85 /* JSTrackEventCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 07B5A30A14687B8400A81ECE /* JSTrackEventCustom.cpp */; };
</span><span class="lines">@@ -1888,7 +1887,7 @@
</span><span class="cx">                 4A0DA2FE129B241900AB61E1 /* FormAssociatedElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4A0DA2FC129B241900AB61E1 /* FormAssociatedElement.cpp */; };
</span><span class="cx">                 4A0DA2FF129B241900AB61E1 /* FormAssociatedElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 4A0DA2FD129B241900AB61E1 /* FormAssociatedElement.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 4A0FFA9D1AAF5E750062803B /* MockRealtimeMediaSourceCenter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4A0FFA9B1AAF5E6C0062803B /* MockRealtimeMediaSourceCenter.cpp */; };
</span><del>-                4A0FFA9E1AAF5E7E0062803B /* MockRealtimeMediaSourceCenter.h in Headers */ = {isa = PBXBuildFile; fileRef = 4A0FFA9C1AAF5E6C0062803B /* MockRealtimeMediaSourceCenter.h */; };
</del><ins>+                4A0FFA9E1AAF5E7E0062803B /* MockRealtimeMediaSourceCenter.h in Headers */ = {isa = PBXBuildFile; fileRef = 4A0FFA9C1AAF5E6C0062803B /* MockRealtimeMediaSourceCenter.h */; settings = {ATTRIBUTES = (Private, ); }; };
</ins><span class="cx">                 4A0FFAA11AAF5EA20062803B /* RealtimeMediaSourceCenter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4A0FFA9F1AAF5EA20062803B /* RealtimeMediaSourceCenter.cpp */; };
</span><span class="cx">                 4A0FFAA21AAF5EA20062803B /* RealtimeMediaSourceCenter.h in Headers */ = {isa = PBXBuildFile; fileRef = 4A0FFAA01AAF5EA20062803B /* RealtimeMediaSourceCenter.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 4A0FFAA51AAF5EF60062803B /* RealtimeMediaSourceCenterMac.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4A0FFAA31AAF5EF60062803B /* RealtimeMediaSourceCenterMac.cpp */; };
</span><span class="lines">@@ -6990,7 +6989,6 @@
</span><span class="cx">                 07221B9117CEC32700848E51 /* UserMediaRequest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UserMediaRequest.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 07221B9917CF0AD400848E51 /* MediaConstraints.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MediaConstraints.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 07221B9D17CF0AD400848E51 /* MediaStreamPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MediaStreamPrivate.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><del>-                07221BA017CF0AD400848E51 /* MediaStreamCreationClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MediaStreamCreationClient.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</del><span class="cx">                 07221BA217CF0AD400848E51 /* RTCDataChannelHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RTCDataChannelHandler.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 07221BA317CF0AD400848E51 /* RTCDataChannelHandlerClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RTCDataChannelHandlerClient.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 07221BA417CF0AD400848E51 /* RTCDTMFSenderHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RTCDTMFSenderHandler.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -7017,8 +7015,6 @@
</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><del>-                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;; };
</del><span class="cx">                 072A703E1D6E8F6200DF0AFC /* OverconstrainedErrorEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OverconstrainedErrorEvent.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 072A703F1D6E8F6200DF0AFC /* OverconstrainedErrorEvent.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = OverconstrainedErrorEvent.idl; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 072A70421D7396B200DF0AFC /* JSMediaDevicesCustom.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSMediaDevicesCustom.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -7127,6 +7123,8 @@
</span><span class="cx">                 07AB996818DA3C010018771E /* RTCIceServer.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = RTCIceServer.idl; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 07AB996D18DA3C740018771E /* RTCConfigurationPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RTCConfigurationPrivate.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 07AB996E18DA3C740018771E /* RTCIceServerPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RTCIceServerPrivate.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                07ABEF6B1D8A1C5800F21972 /* MediaDevicesEnumerationRequest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MediaDevicesEnumerationRequest.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                07ABEF6D1D8A1C7600F21972 /* MediaDevicesEnumerationRequest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MediaDevicesEnumerationRequest.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 07AC46FF1952102100EE9723 /* ISOVTTCue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ISOVTTCue.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 07AC47001952102100EE9723 /* ISOVTTCue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ISOVTTCue.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 07B0113E1032242200FBDC33 /* AccessibilityMediaControls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AccessibilityMediaControls.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -14694,6 +14692,8 @@
</span><span class="cx">                                 5EA725CD1ACABCD900EAD17B /* MediaDevices.cpp */,
</span><span class="cx">                                 5EA725CE1ACABCD900EAD17B /* MediaDevices.h */,
</span><span class="cx">                                 5EA725CF1ACABCD900EAD17B /* MediaDevices.idl */,
</span><ins>+                                 07ABEF6B1D8A1C5800F21972 /* MediaDevicesEnumerationRequest.cpp */,
+                                 07ABEF6D1D8A1C7600F21972 /* MediaDevicesEnumerationRequest.h */,
</ins><span class="cx">                                 07394EC71BAB2CCD00BE99CD /* MediaDevicesRequest.cpp */,
</span><span class="cx">                                 07394EC91BAB2CD700BE99CD /* MediaDevicesRequest.h */,
</span><span class="cx">                                 5E16A2E21BFA64FB0029A21E /* MediaEndpointPeerConnection.cpp */,
</span><span class="lines">@@ -14796,8 +14796,6 @@
</span><span class="cx">                                 07221B8D17CEC32700848E51 /* UserMediaClient.h */,
</span><span class="cx">                                 07221B8E17CEC32700848E51 /* UserMediaController.cpp */,
</span><span class="cx">                                 07221B8F17CEC32700848E51 /* UserMediaController.h */,
</span><del>-                                07297FA51C1881C5003F0735 /* UserMediaPermissionCheck.cpp */,
-                                07297FA61C1881C5003F0735 /* UserMediaPermissionCheck.h */,
</del><span class="cx">                                 07221B9017CEC32700848E51 /* UserMediaRequest.cpp */,
</span><span class="cx">                                 07221B9117CEC32700848E51 /* UserMediaRequest.h */,
</span><span class="cx">                         );
</span><span class="lines">@@ -14822,7 +14820,6 @@
</span><span class="cx">                                 5EBB892E1C7777D000C65D41 /* MediaEndpointSessionConfiguration.h */,
</span><span class="cx">                                 5EBB892F1C7777D000C65D41 /* MediaPayload.h */,
</span><span class="cx">                                 070F549717F12F6B00169E04 /* MediaStreamConstraintsValidationClient.h */,
</span><del>-                                07221BA017CF0AD400848E51 /* MediaStreamCreationClient.h */,
</del><span class="cx">                                 0711588F17DF633700EDFE2B /* MediaStreamPrivate.cpp */,
</span><span class="cx">                                 07221B9D17CF0AD400848E51 /* MediaStreamPrivate.h */,
</span><span class="cx">                                 07FFDE66181AED420072D409 /* MediaStreamTrackPrivate.cpp */,
</span><span class="lines">@@ -25501,6 +25498,7 @@
</span><span class="cx">                                 7694563D1214D97C0007CBAE /* JSDOMTokenList.h in Headers */,
</span><span class="cx">                                 2E37E00612DBC5A400A6B233 /* JSDOMURL.h in Headers */,
</span><span class="cx">                                 BC6932740D7E293900AE44D1 /* JSDOMWindowBase.h in Headers */,
</span><ins>+                                07ABEF6E1D8A1C7600F21972 /* MediaDevicesEnumerationRequest.h in Headers */,
</ins><span class="cx">                                 652FBBBC0DE27CB60001D386 /* JSDOMWindowCustom.h in Headers */,
</span><span class="cx">                                 460CBF361D4BCD0E0092E88E /* JSDOMWindowProperties.h in Headers */,
</span><span class="cx">                                 BCBFB53D0DCD29CF0019B3E5 /* JSDOMWindowShell.h in Headers */,
</span><span class="lines">@@ -26169,7 +26167,6 @@
</span><span class="cx">                                 0783228518013ED800999E0C /* MediaStreamAudioSource.h in Headers */,
</span><span class="cx">                                 FD671A78159BB07000197559 /* MediaStreamAudioSourceNode.h in Headers */,
</span><span class="cx">                                 070F549817F12F6B00169E04 /* MediaStreamConstraintsValidationClient.h in Headers */,
</span><del>-                                078E093917D16B2C00420AA1 /* MediaStreamCreationClient.h in Headers */,
</del><span class="cx">                                 078E091617D14D1C00420AA1 /* MediaStreamEvent.h in Headers */,
</span><span class="cx">                                 078E093717D16B2C00420AA1 /* MediaStreamPrivate.h in Headers */,
</span><span class="cx">                                 078E091717D14D1C00420AA1 /* MediaStreamRegistry.h in Headers */,
</span><span class="lines">@@ -27416,7 +27413,6 @@
</span><span class="cx">                                 71C916081D1483A300ACA47D /* UserInterfaceLayoutDirection.h in Headers */,
</span><span class="cx">                                 078E092E17D14D1C00420AA1 /* UserMediaClient.h in Headers */,
</span><span class="cx">                                 078E092F17D14D1C00420AA1 /* UserMediaController.h in Headers */,
</span><del>-                                07297FA81C1881C5003F0735 /* UserMediaPermissionCheck.h in Headers */,
</del><span class="cx">                                 078E093017D14D1C00420AA1 /* UserMediaRequest.h in Headers */,
</span><span class="cx">                                 7C3B79721908757B00B47A2D /* UserMessageHandler.h in Headers */,
</span><span class="cx">                                 7CE68345192143A800F4D928 /* UserMessageHandlerDescriptor.h in Headers */,
</span><span class="lines">@@ -29867,6 +29863,7 @@
</span><span class="cx">                                 CDAB6D2817C7DE6C00C60B34 /* MediaControlsHost.cpp in Sources */,
</span><span class="cx">                                 159AE82B1B3A402F0037478B /* MediaDeviceInfo.cpp in Sources */,
</span><span class="cx">                                 5EA725D21ACABD4700EAD17B /* MediaDevices.cpp in Sources */,
</span><ins>+                                07ABEF6C1D8A1C5800F21972 /* MediaDevicesEnumerationRequest.cpp in Sources */,
</ins><span class="cx">                                 07394EC81BAB2CCD00BE99CD /* MediaDevicesRequest.cpp in Sources */,
</span><span class="cx">                                 97205AB71239291000B17380 /* MediaDocument.cpp in Sources */,
</span><span class="cx">                                 FD6F252C13F5EF0E0065165F /* MediaElementAudioSourceNode.cpp in Sources */,
</span><span class="lines">@@ -30880,7 +30877,6 @@
</span><span class="cx">                                 2542F4DA1166C25A00E89A86 /* UserGestureIndicator.cpp in Sources */,
</span><span class="cx">                                 9920398218B95BC600B39AF9 /* UserInputBridge.cpp in Sources */,
</span><span class="cx">                                 078E091217D14CEE00420AA1 /* UserMediaController.cpp in Sources */,
</span><del>-                                07297FA71C1881C5003F0735 /* UserMediaPermissionCheck.cpp in Sources */,
</del><span class="cx">                                 078E091317D14CEE00420AA1 /* UserMediaRequest.cpp in Sources */,
</span><span class="cx">                                 7C3B79711908757B00B47A2D /* UserMessageHandler.cpp in Sources */,
</span><span class="cx">                                 7CE68344192143A800F4D928 /* UserMessageHandlerDescriptor.cpp in Sources */,
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformmediastreamCaptureDeviceh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/mediastream/CaptureDevice.h (207462 => 207463)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/mediastream/CaptureDevice.h        2016-10-18 13:15:40 UTC (rev 207462)
+++ trunk/Source/WebCore/platform/mediastream/CaptureDevice.h        2016-10-18 14:53:06 UTC (rev 207463)
</span><span class="lines">@@ -27,7 +27,6 @@
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(MEDIA_STREAM)
</span><span class="cx"> 
</span><del>-#include &lt;RealtimeMediaSource.h&gt;
</del><span class="cx"> #include &lt;wtf/text/WTFString.h&gt;
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="lines">@@ -34,7 +33,7 @@
</span><span class="cx"> 
</span><span class="cx"> class CaptureDevice {
</span><span class="cx"> public:
</span><del>-    enum class SourceKind { Audio, Video };
</del><ins>+    enum class SourceKind { Unknown, Audio, Video };
</ins><span class="cx"> 
</span><span class="cx">     CaptureDevice(const String&amp; persistentId, SourceKind kind, const String&amp; label, const String&amp; groupId)
</span><span class="cx">         : m_persistentId(persistentId)
</span><span class="lines">@@ -44,14 +43,23 @@
</span><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    CaptureDevice() = default;
+
</ins><span class="cx">     const String&amp; persistentId() const { return m_persistentId; }
</span><ins>+    void setPersistentId(const String&amp; id) { m_persistentId = id; }
+
</ins><span class="cx">     const String&amp; label() const { return m_label; }
</span><ins>+    void setLabel(const String&amp; label) { m_label = label; }
+
</ins><span class="cx">     const String&amp; groupId() const { return m_groupId; }
</span><ins>+    void setGroupId(const String&amp; id) { m_groupId = id; }
+
</ins><span class="cx">     SourceKind kind() const { return m_kind; }
</span><ins>+    void setKind(SourceKind kind) { m_kind = kind; }
</ins><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     String m_persistentId;
</span><del>-    SourceKind m_kind;
</del><ins>+    SourceKind m_kind { SourceKind::Unknown };
</ins><span class="cx">     String m_label;
</span><span class="cx">     String m_groupId;
</span><span class="cx"> };
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformmediastreamCaptureDeviceManagerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/mediastream/CaptureDeviceManager.h (207462 => 207463)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/mediastream/CaptureDeviceManager.h        2016-10-18 13:15:40 UTC (rev 207462)
+++ trunk/Source/WebCore/platform/mediastream/CaptureDeviceManager.h        2016-10-18 14:53:06 UTC (rev 207463)
</span><span class="lines">@@ -28,6 +28,7 @@
</span><span class="cx"> #if ENABLE(MEDIA_STREAM)
</span><span class="cx"> 
</span><span class="cx"> #include &quot;CaptureDevice.h&quot;
</span><ins>+#include &quot;RealtimeMediaSource.h&quot;
</ins><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformmediastreamMediaConstraintscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/mediastream/MediaConstraints.cpp (207462 => 207463)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/mediastream/MediaConstraints.cpp        2016-10-18 13:15:40 UTC (rev 207462)
+++ trunk/Source/WebCore/platform/mediastream/MediaConstraints.cpp        2016-10-18 14:53:06 UTC (rev 207463)
</span><span class="lines">@@ -38,65 +38,6 @@
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><del>-bool BooleanConstraint::getExact(bool&amp; exact) const
-{
-    if (!m_exact)
-        return false;
-    
-    exact = m_exact.value();
-    return true;
-}
-
-bool BooleanConstraint::getIdeal(bool&amp; ideal) const
-{
-    if (!m_ideal)
-        return false;
-    
-    ideal = m_ideal.value();
-    return true;
-}
-
-void StringConstraint::setExact(const String&amp; value)
-{
-    m_exact.clear();
-    m_exact.append(value);
-}
-
-void StringConstraint::appendExact(const String&amp; value)
-{
-    m_exact.clear();
-    m_exact.append(value);
-}
-
-void StringConstraint::setIdeal(const String&amp; value)
-{
-    m_ideal.clear();
-    m_ideal.append(value);
-}
-
-void StringConstraint::appendIdeal(const String&amp; value)
-{
-    m_ideal.append(value);
-}
-
-bool StringConstraint::getExact(Vector&lt;String&gt;&amp; exact) const
-{
-    if (!m_exact.isEmpty())
-        return false;
-
-    exact = m_exact;
-    return true;
-}
-
-bool StringConstraint::getIdeal(Vector&lt;String&gt;&amp; ideal) const
-{
-    if (!m_ideal.isEmpty())
-        return false;
-
-    ideal = m_ideal;
-    return true;
-}
-
</del><span class="cx"> const String&amp; StringConstraint::find(std::function&lt;bool(const String&amp;)&gt; filter) const
</span><span class="cx"> {
</span><span class="cx">     for (auto&amp; constraint : m_exact) {
</span><span class="lines">@@ -153,7 +94,7 @@
</span><span class="cx">     ASSERT(other.isString());
</span><span class="cx">     const StringConstraint&amp; typedOther = downcast&lt;StringConstraint&gt;(other);
</span><span class="cx"> 
</span><del>-    if (other.isEmpty())
</del><ins>+    if (typedOther.isEmpty())
</ins><span class="cx">         return;
</span><span class="cx"> 
</span><span class="cx">     Vector&lt;String&gt; values;
</span><span class="lines">@@ -229,36 +170,14 @@
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx">     m_variants.append(ConstraintHolder::create(constraint));
</span><del>-
</del><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void MediaTrackConstraintSetMap::forEach(std::function&lt;void(const MediaConstraint&amp;)&gt; callback) const
</span><span class="cx"> {
</span><del>-    if (m_width &amp;&amp; !m_width-&gt;isEmpty())
-        callback(*m_width);
-    if (m_height &amp;&amp; !m_height-&gt;isEmpty())
-        callback(*m_height);
-    if (m_sampleRate &amp;&amp; !m_sampleRate-&gt;isEmpty())
-        callback(*m_sampleRate);
-    if (m_sampleSize &amp;&amp; !m_sampleSize-&gt;isEmpty())
-        callback(*m_sampleSize);
-
-    if (m_aspectRatio &amp;&amp; !m_aspectRatio-&gt;isEmpty())
-        callback(*m_aspectRatio);
-    if (m_frameRate &amp;&amp; !m_frameRate-&gt;isEmpty())
-        callback(*m_frameRate);
-    if (m_volume &amp;&amp; !m_volume-&gt;isEmpty())
-        callback(*m_volume);
-
-    if (m_echoCancellation &amp;&amp; !m_echoCancellation-&gt;isEmpty())
-        callback(*m_echoCancellation);
-
-    if (m_facingMode &amp;&amp; !m_facingMode-&gt;isEmpty())
-        callback(*m_facingMode);
-    if (m_deviceId &amp;&amp; !m_deviceId-&gt;isEmpty())
-        callback(*m_deviceId);
-    if (m_groupId &amp;&amp; !m_groupId-&gt;isEmpty())
-        callback(*m_groupId);
</del><ins>+    filter([callback] (const MediaConstraint&amp; constraint) mutable {
+        callback(constraint);
+        return false;
+    });
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void MediaTrackConstraintSetMap::filter(std::function&lt;bool(const MediaConstraint&amp;)&gt; callback) const
</span><span class="lines">@@ -290,21 +209,6 @@
</span><span class="cx">         return;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool MediaTrackConstraintSetMap::isEmpty() const
-{
-    return (!m_width || m_width-&gt;isEmpty())
-        &amp;&amp; (!m_height || m_height-&gt;isEmpty())
-        &amp;&amp; (!m_sampleRate || m_sampleRate-&gt;isEmpty())
-        &amp;&amp; (!m_sampleSize || m_sampleSize-&gt;isEmpty())
-        &amp;&amp; (!m_aspectRatio || m_aspectRatio-&gt;isEmpty())
-        &amp;&amp; (!m_frameRate || m_frameRate-&gt;isEmpty())
-        &amp;&amp; (!m_volume || m_volume-&gt;isEmpty())
-        &amp;&amp; (!m_echoCancellation || m_echoCancellation-&gt;isEmpty())
-        &amp;&amp; (!m_facingMode || m_facingMode-&gt;isEmpty())
-        &amp;&amp; (!m_deviceId || m_deviceId-&gt;isEmpty())
-        &amp;&amp; (!m_groupId || m_groupId-&gt;isEmpty());
-}
-
</del><span class="cx"> void MediaTrackConstraintSetMap::set(MediaConstraintType constraintType, Optional&lt;IntConstraint&gt;&amp;&amp; constraint)
</span><span class="cx"> {
</span><span class="cx">     switch (constraintType) {
</span><span class="lines">@@ -411,6 +315,21 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+size_t MediaTrackConstraintSetMap::size() const
+{
+    size_t count = 0;
+    forEach([&amp;count] (const MediaConstraint&amp;) mutable {
+        ++count;
+    });
+
+    return count;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><ins>+bool MediaTrackConstraintSetMap::isEmpty() const
+{
+    return !size();
+}
+
+}
+
</ins><span class="cx"> #endif // ENABLE(MEDIA_STREAM)
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformmediastreamMediaConstraintsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/mediastream/MediaConstraints.h (207462 => 207463)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/mediastream/MediaConstraints.h        2016-10-18 13:15:40 UTC (rev 207462)
+++ trunk/Source/WebCore/platform/mediastream/MediaConstraints.h        2016-10-18 14:53:06 UTC (rev 207463)
</span><span class="lines">@@ -48,12 +48,6 @@
</span><span class="cx"> public:
</span><span class="cx">     enum class DataType { None, Integer, Double, Boolean, String };
</span><span class="cx"> 
</span><del>-    virtual ~MediaConstraint() { };
-
-    virtual bool isEmpty() const { return true; }
-    virtual bool isMandatory() const { return false; }
-    virtual void merge(const MediaConstraint&amp;) { }
-
</del><span class="cx">     bool isInt() const { return m_dataType == DataType::Integer; }
</span><span class="cx">     bool isDouble() const { return m_dataType == DataType::Double; }
</span><span class="cx">     bool isBoolean() const { return m_dataType == DataType::Boolean; }
</span><span class="lines">@@ -63,8 +57,29 @@
</span><span class="cx">     MediaConstraintType constraintType() const { return m_constraintType; }
</span><span class="cx">     const String&amp; name() const { return m_name; }
</span><span class="cx"> 
</span><ins>+    template &lt;class Encoder&gt; void encode(Encoder&amp; encoder) const
+    {
+        encoder.encodeEnum(m_constraintType);
+        encoder &lt;&lt; m_name;
+        encoder.encodeEnum(m_dataType);
+    }
+
+    template &lt;class Decoder&gt; static bool decode(Decoder&amp; decoder, MediaConstraint&amp; constraint)
+    {
+        if (!decoder.decodeEnum(constraint.m_constraintType))
+            return false;
+
+        if (!decoder.decode(constraint.m_name))
+            return false;
+
+        if (!decoder.decodeEnum(constraint.m_dataType))
+            return false;
+
+        return true;
+    }
+
</ins><span class="cx"> protected:
</span><del>-    explicit MediaConstraint(const AtomicString&amp; name, MediaConstraintType constraintType, DataType dataType)
</del><ins>+    MediaConstraint(const String&amp; name, MediaConstraintType constraintType, DataType dataType)
</ins><span class="cx">         : m_name(name)
</span><span class="cx">         , m_constraintType(constraintType)
</span><span class="cx">         , m_dataType(dataType)
</span><span class="lines">@@ -71,11 +86,13 @@
</span><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    MediaConstraint() = default;
+    ~MediaConstraint() = default;
</ins><span class="cx"> 
</span><span class="cx"> private:
</span><del>-    AtomicString m_name;
-    MediaConstraintType m_constraintType;
-    DataType m_dataType;
</del><ins>+    String m_name;
+    MediaConstraintType m_constraintType { MediaConstraintType::Unknown };
+    DataType m_dataType { DataType::None };
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> template&lt;class ValueType&gt;
</span><span class="lines">@@ -212,15 +229,44 @@
</span><span class="cx">         return 0;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    bool isEmpty() const override { return !m_min &amp;&amp; !m_max &amp;&amp; !m_exact &amp;&amp; !m_ideal; }
-    bool isMandatory() const override { return m_min || m_max || m_exact; }
</del><ins>+    bool isEmpty() const { return !m_min &amp;&amp; !m_max &amp;&amp; !m_exact &amp;&amp; !m_ideal; }
+    bool isMandatory() const { return m_min || m_max || m_exact; }
</ins><span class="cx"> 
</span><ins>+    template &lt;class Encoder&gt; void encode(Encoder&amp; encoder) const
+    {
+        MediaConstraint::encode(encoder);
+
+        encoder &lt;&lt; m_min;
+        encoder &lt;&lt; m_max;
+        encoder &lt;&lt; m_exact;
+        encoder &lt;&lt; m_ideal;
+    }
+
+    template &lt;class Decoder&gt; static bool decode(Decoder&amp; decoder, NumericConstraint&amp; constraint)
+    {
+        if (!MediaConstraint::decode(decoder, constraint))
+            return false;
+
+        if (!decoder.decode(constraint.m_min))
+            return false;
+        if (!decoder.decode(constraint.m_max))
+            return false;
+        if (!decoder.decode(constraint.m_exact))
+            return false;
+        if (!decoder.decode(constraint.m_ideal))
+            return false;
+    
+        return true;
+    }
+
</ins><span class="cx"> protected:
</span><del>-    explicit NumericConstraint(const AtomicString&amp; name, MediaConstraintType type, DataType dataType)
</del><ins>+    NumericConstraint(const String&amp; name, MediaConstraintType type, DataType dataType)
</ins><span class="cx">         : MediaConstraint(name, type, dataType)
</span><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    NumericConstraint() = default;
+
</ins><span class="cx">     void innerMerge(const NumericConstraint&amp; other)
</span><span class="cx">     {
</span><span class="cx">         if (other.isEmpty())
</span><span class="lines">@@ -255,12 +301,15 @@
</span><span class="cx"> 
</span><span class="cx"> class IntConstraint final : public NumericConstraint&lt;int&gt; {
</span><span class="cx"> public:
</span><del>-    explicit IntConstraint(const AtomicString&amp; name, MediaConstraintType type)
</del><ins>+    IntConstraint(const String&amp; name, MediaConstraintType type)
</ins><span class="cx">         : NumericConstraint&lt;int&gt;(name, type, DataType::Integer)
</span><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    void merge(const MediaConstraint&amp; other) final {
</del><ins>+    IntConstraint() = default;
+
+    void merge(const MediaConstraint&amp; other)
+    {
</ins><span class="cx">         ASSERT(other.isInt());
</span><span class="cx">         NumericConstraint::innerMerge(downcast&lt;const IntConstraint&gt;(other));
</span><span class="cx">     }
</span><span class="lines">@@ -268,12 +317,15 @@
</span><span class="cx"> 
</span><span class="cx"> class DoubleConstraint final : public NumericConstraint&lt;double&gt; {
</span><span class="cx"> public:
</span><del>-    explicit DoubleConstraint(const AtomicString&amp; name, MediaConstraintType type)
</del><ins>+    DoubleConstraint(const String&amp; name, MediaConstraintType type)
</ins><span class="cx">         : NumericConstraint&lt;double&gt;(name, type, DataType::Double)
</span><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    void merge(const MediaConstraint&amp; other) final {
</del><ins>+    DoubleConstraint() = default;
+
+    void merge(const MediaConstraint&amp; other)
+    {
</ins><span class="cx">         ASSERT(other.isDouble());
</span><span class="cx">         NumericConstraint::innerMerge(downcast&lt;DoubleConstraint&gt;(other));
</span><span class="cx">     }
</span><span class="lines">@@ -281,17 +333,34 @@
</span><span class="cx"> 
</span><span class="cx"> class BooleanConstraint final : public MediaConstraint {
</span><span class="cx"> public:
</span><del>-    explicit BooleanConstraint(const AtomicString&amp; name, MediaConstraintType type)
</del><ins>+    BooleanConstraint(const String&amp; name, MediaConstraintType type)
</ins><span class="cx">         : MediaConstraint(name, type, DataType::Boolean)
</span><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    BooleanConstraint() = default;
+
</ins><span class="cx">     void setExact(bool value) { m_exact = value; }
</span><span class="cx">     void setIdeal(bool value) { m_ideal = value; }
</span><span class="cx"> 
</span><del>-    bool getExact(bool&amp;) const;
-    bool getIdeal(bool&amp;) const;
</del><ins>+    bool getExact(bool&amp; exact) const
+    {
+        if (!m_exact)
+            return false;
</ins><span class="cx"> 
</span><ins>+        exact = m_exact.value();
+        return true;
+    }
+
+    bool getIdeal(bool&amp; ideal) const
+    {
+        if (!m_ideal)
+            return false;
+
+        ideal = m_ideal.value();
+        return true;
+    }
+
</ins><span class="cx">     double fitnessDistance(bool value) const
</span><span class="cx">     {
</span><span class="cx">         // https://w3c.github.io/mediacapture-main/#dfn-applyconstraints
</span><span class="lines">@@ -315,7 +384,8 @@
</span><span class="cx">         return 1;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    void merge(const MediaConstraint&amp; other) final {
</del><ins>+    void merge(const MediaConstraint&amp; other)
+    {
</ins><span class="cx">         ASSERT(other.isBoolean());
</span><span class="cx">         const BooleanConstraint&amp; typedOther = downcast&lt;BooleanConstraint&gt;(other);
</span><span class="cx"> 
</span><span class="lines">@@ -332,38 +402,114 @@
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    bool isEmpty() const final { return !m_exact &amp;&amp; !m_ideal; };
-    bool isMandatory() const final { return bool(m_exact); }
</del><ins>+    bool isEmpty() const { return !m_exact &amp;&amp; !m_ideal; };
+    bool isMandatory() const { return bool(m_exact); }
</ins><span class="cx"> 
</span><ins>+    template &lt;class Encoder&gt; void encode(Encoder&amp; encoder) const
+    {
+        MediaConstraint::encode(encoder);
+        encoder &lt;&lt; m_exact;
+        encoder &lt;&lt; m_ideal;
+    }
+
+    template &lt;class Decoder&gt; static bool decode(Decoder&amp; decoder, BooleanConstraint&amp; constraint)
+    {
+        if (!MediaConstraint::decode(decoder, constraint))
+            return false;
+
+        if (!decoder.decode(constraint.m_exact))
+            return false;
+        if (!decoder.decode(constraint.m_ideal))
+            return false;
+
+        return true;
+    }
+
</ins><span class="cx"> private:
</span><span class="cx">     Optional&lt;bool&gt; m_exact;
</span><span class="cx">     Optional&lt;bool&gt; m_ideal;
</span><span class="cx"> };
</span><span class="cx"> 
</span><del>-class StringConstraint final : public MediaConstraint {
</del><ins>+class StringConstraint : public MediaConstraint {
</ins><span class="cx"> public:
</span><del>-    explicit StringConstraint(const AtomicString&amp; name, MediaConstraintType type)
</del><ins>+    StringConstraint(const String&amp; name, MediaConstraintType type)
</ins><span class="cx">         : MediaConstraint(name, type, DataType::String)
</span><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    void setExact(const String&amp;);
-    void appendExact(const String&amp;);
-    void setIdeal(const String&amp;);
-    void appendIdeal(const String&amp;);
</del><ins>+    StringConstraint() = default;
</ins><span class="cx"> 
</span><del>-    bool getExact(Vector&lt;String&gt;&amp;) const;
-    bool getIdeal(Vector&lt;String&gt;&amp;) const;
</del><ins>+    void setExact(const String&amp; value)
+    {
+        m_exact.clear();
+        m_exact.append(value);
+    }
</ins><span class="cx"> 
</span><ins>+    void appendExact(const String&amp; value)
+    {
+        m_exact.clear();
+        m_exact.append(value);
+    }
+
+    void setIdeal(const String&amp; value)
+    {
+        m_ideal.clear();
+        m_ideal.append(value);
+    }
+
+    void appendIdeal(const String&amp; value)
+    {
+        m_ideal.append(value);
+    }
+
+    bool getExact(Vector&lt;String&gt;&amp; exact) const
+    {
+        if (!m_exact.isEmpty())
+            return false;
+
+        exact = m_exact;
+        return true;
+    }
+
+    bool getIdeal(Vector&lt;String&gt;&amp; ideal) const
+    {
+        if (!m_ideal.isEmpty())
+            return false;
+
+        ideal = m_ideal;
+        return true;
+    }
+
</ins><span class="cx">     double fitnessDistance(const String&amp;) const;
</span><span class="cx">     double fitnessDistance(const Vector&lt;String&gt;&amp;) const;
</span><span class="cx"> 
</span><span class="cx">     const String&amp; find(std::function&lt;bool(const String&amp;)&gt;) const;
</span><del>-    void merge(const MediaConstraint&amp;) final;
</del><span class="cx"> 
</span><del>-    bool isEmpty() const final { return m_exact.isEmpty() &amp;&amp; m_ideal.isEmpty(); }
-    bool isMandatory() const final { return !m_exact.isEmpty(); }
</del><ins>+    bool isEmpty() const { return m_exact.isEmpty() &amp;&amp; m_ideal.isEmpty(); }
+    bool isMandatory() const { return !m_exact.isEmpty(); }
+    WEBCORE_EXPORT void merge(const MediaConstraint&amp;);
</ins><span class="cx"> 
</span><ins>+    template &lt;class Encoder&gt; void encode(Encoder&amp; encoder) const
+    {
+        MediaConstraint::encode(encoder);
+
+        encoder &lt;&lt; m_exact;
+        encoder &lt;&lt; m_ideal;
+    }
+
+    template &lt;class Decoder&gt; static bool decode(Decoder&amp; decoder, StringConstraint&amp; constraint)
+    {
+        if (!MediaConstraint::decode(decoder, constraint))
+            return false;
+
+        if (!decoder.decode(constraint.m_exact))
+            return false;
+        if (!decoder.decode(constraint.m_ideal))
+            return false;
+
+        return true;
+    }
+
</ins><span class="cx"> private:
</span><span class="cx">     Vector&lt;String&gt; m_exact;
</span><span class="cx">     Vector&lt;String&gt; m_ideal;
</span><span class="lines">@@ -371,28 +517,78 @@
</span><span class="cx"> 
</span><span class="cx"> class UnknownConstraint final : public MediaConstraint {
</span><span class="cx"> public:
</span><del>-    explicit UnknownConstraint(const AtomicString&amp; name, MediaConstraintType type)
</del><ins>+    UnknownConstraint(const String&amp; name, MediaConstraintType type)
</ins><span class="cx">         : MediaConstraint(name, type, DataType::None)
</span><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx"> private:
</span><del>-    bool isEmpty() const final { return true; }
-    bool isMandatory() const final { return false; }
-    void merge(const MediaConstraint&amp;) final { }
</del><ins>+    bool isEmpty() const { return true; }
+    bool isMandatory() const { return false; }
+    void merge(const MediaConstraint&amp;) { }
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> class MediaTrackConstraintSetMap {
</span><span class="cx"> public:
</span><del>-    void forEach(std::function&lt;void(const MediaConstraint&amp;)&gt;) const;
</del><ins>+    WEBCORE_EXPORT void forEach(std::function&lt;void(const MediaConstraint&amp;)&gt;) const;
</ins><span class="cx">     void filter(std::function&lt;bool(const MediaConstraint&amp;)&gt;) const;
</span><span class="cx">     bool isEmpty() const;
</span><ins>+    WEBCORE_EXPORT size_t size() const;
</ins><span class="cx"> 
</span><del>-    void set(MediaConstraintType, Optional&lt;IntConstraint&gt;&amp;&amp;);
-    void set(MediaConstraintType, Optional&lt;DoubleConstraint&gt;&amp;&amp;);
-    void set(MediaConstraintType, Optional&lt;BooleanConstraint&gt;&amp;&amp;);
-    void set(MediaConstraintType, Optional&lt;StringConstraint&gt;&amp;&amp;);
</del><ins>+    WEBCORE_EXPORT void set(MediaConstraintType, Optional&lt;IntConstraint&gt;&amp;&amp;);
+    WEBCORE_EXPORT void set(MediaConstraintType, Optional&lt;DoubleConstraint&gt;&amp;&amp;);
+    WEBCORE_EXPORT void set(MediaConstraintType, Optional&lt;BooleanConstraint&gt;&amp;&amp;);
+    WEBCORE_EXPORT void set(MediaConstraintType, Optional&lt;StringConstraint&gt;&amp;&amp;);
</ins><span class="cx"> 
</span><ins>+    template &lt;class Encoder&gt; void encode(Encoder&amp; encoder) const
+    {
+        encoder &lt;&lt; m_width;
+        encoder &lt;&lt; m_height;
+        encoder &lt;&lt; m_sampleRate;
+        encoder &lt;&lt; m_sampleSize;
+
+        encoder &lt;&lt; m_aspectRatio;
+        encoder &lt;&lt; m_frameRate;
+        encoder &lt;&lt; m_volume;
+
+        encoder &lt;&lt; m_echoCancellation;
+
+        encoder &lt;&lt; m_facingMode;
+        encoder &lt;&lt; m_deviceId;
+        encoder &lt;&lt; m_groupId;
+    }
+
+    template &lt;class Decoder&gt; static bool decode(Decoder&amp; decoder, MediaTrackConstraintSetMap&amp; map)
+    {
+        if (!decoder.decode(map.m_width))
+            return false;
+        if (!decoder.decode(map.m_height))
+            return false;
+        if (!decoder.decode(map.m_sampleRate))
+            return false;
+        if (!decoder.decode(map.m_sampleSize))
+            return false;
+
+        if (!decoder.decode(map.m_aspectRatio))
+            return false;
+        if (!decoder.decode(map.m_frameRate))
+            return false;
+        if (!decoder.decode(map.m_volume))
+            return false;
+
+        if (!decoder.decode(map.m_echoCancellation))
+            return false;
+
+        if (!decoder.decode(map.m_facingMode))
+            return false;
+        if (!decoder.decode(map.m_deviceId))
+            return false;
+        if (!decoder.decode(map.m_groupId))
+            return false;
+
+        return true;
+    }
+
</ins><span class="cx"> private:
</span><span class="cx">     Optional&lt;IntConstraint&gt; m_width;
</span><span class="cx">     Optional&lt;IntConstraint&gt; m_height;
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformmediastreamMediaStreamCreationClienth"></a>
<div class="delfile"><h4>Deleted: trunk/Source/WebCore/platform/mediastream/MediaStreamCreationClient.h (207462 => 207463)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/mediastream/MediaStreamCreationClient.h        2016-10-18 13:15:40 UTC (rev 207462)
+++ trunk/Source/WebCore/platform/mediastream/MediaStreamCreationClient.h        2016-10-18 14:53:06 UTC (rev 207463)
</span><span class="lines">@@ -1,53 +0,0 @@
</span><del>-/*
- * Copyright (C) 2013-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 MediaStreamCreationClient_h
-#define MediaStreamCreationClient_h
-
-#if ENABLE(MEDIA_STREAM)
-
-#include &quot;MediaDevices.h&quot;
-#include &quot;RealtimeMediaSource.h&quot;
-#include &lt;wtf/RefCounted.h&gt;
-
-namespace WebCore {
-
-class MediaStreamCreationClient : public RefCounted&lt;MediaStreamCreationClient&gt; {
-public:
-    virtual ~MediaStreamCreationClient() { }
-
-    virtual void constraintsValidated(const Vector&lt;RefPtr&lt;RealtimeMediaSource&gt;&gt;&amp; audioTracks, const Vector&lt;RefPtr&lt;RealtimeMediaSource&gt;&gt;&amp; videoTracks) = 0;
-    virtual void constraintsInvalid(const String&amp; constraintName) = 0;
-
-    virtual void didCreateStream(RefPtr&lt;MediaStreamPrivate&gt;&amp;&amp;) = 0;
-    virtual void failedToCreateStreamWithConstraintsError(const String&amp; constraintName) = 0;
-    virtual void failedToCreateStreamWithPermissionError() = 0;
-};
-
-} // namespace WebCore
-
-#endif // ENABLE(MEDIA_STREAM)
-
-#endif // MediaStreamCreationClient_h
</del></span></pre></div>
<a id="trunkSourceWebCoreplatformmediastreamRealtimeMediaSourceCenterh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/mediastream/RealtimeMediaSourceCenter.h (207462 => 207463)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/mediastream/RealtimeMediaSourceCenter.h        2016-10-18 13:15:40 UTC (rev 207462)
+++ trunk/Source/WebCore/platform/mediastream/RealtimeMediaSourceCenter.h        2016-10-18 14:53:06 UTC (rev 207463)
</span><span class="lines">@@ -43,7 +43,6 @@
</span><span class="cx"> 
</span><span class="cx"> class CaptureDevice;
</span><span class="cx"> class MediaConstraints;
</span><del>-class MediaStreamCreationClient;
</del><span class="cx"> class RealtimeMediaSourceSettings;
</span><span class="cx"> class RealtimeMediaSourceSupportedConstraints;
</span><span class="cx"> class TrackSourceInfo;
</span><span class="lines">@@ -55,12 +54,13 @@
</span><span class="cx">     WEBCORE_EXPORT static RealtimeMediaSourceCenter&amp; singleton();
</span><span class="cx">     static void setSharedStreamCenterOverride(RealtimeMediaSourceCenter*);
</span><span class="cx"> 
</span><del>-    virtual void validateRequestConstraints(MediaStreamCreationClient*, MediaConstraints&amp; audioConstraints, MediaConstraints&amp; videoConstraints) = 0;
</del><ins>+    using ValidConstraintsHandler = std::function&lt;void(const Vector&lt;RefPtr&lt;RealtimeMediaSource&gt;&gt;&amp;&amp; audioTracks, const Vector&lt;RefPtr&lt;RealtimeMediaSource&gt;&gt;&amp;&amp; videoTracks)&gt;;
+    using InvalidConstraintsHandler = std::function&lt;void(const String&amp; invalidConstraint)&gt;;
+    virtual void validateRequestConstraints(ValidConstraintsHandler, InvalidConstraintsHandler, MediaConstraints&amp; audioConstraints, MediaConstraints&amp; videoConstraints) = 0;
</ins><span class="cx"> 
</span><del>-    virtual void createMediaStream(MediaStreamCreationClient*, const String&amp; audioDeviceID, const String&amp; videoDeviceID) = 0;
</del><ins>+    using NewMediaStreamHandler = std::function&lt;void(RefPtr&lt;MediaStreamPrivate&gt;&amp;&amp;)&gt;;
+    virtual void createMediaStream(NewMediaStreamHandler, const String&amp; audioDeviceID, const String&amp; videoDeviceID) = 0;
</ins><span class="cx"> 
</span><del>-    virtual void createMediaStream(PassRefPtr&lt;MediaStreamCreationClient&gt;, MediaConstraints&amp; audioConstraints, MediaConstraints&amp; videoConstraints) = 0;
-
</del><span class="cx">     virtual Vector&lt;CaptureDevice&gt; getMediaStreamDevices() = 0;
</span><span class="cx">     
</span><span class="cx">     virtual const RealtimeMediaSourceSupportedConstraints&amp; supportedConstraints() { return m_supportedConstraints; }
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformmediastreammacAVCaptureDeviceManagermm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/mediastream/mac/AVCaptureDeviceManager.mm (207462 => 207463)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/mediastream/mac/AVCaptureDeviceManager.mm        2016-10-18 13:15:40 UTC (rev 207462)
+++ trunk/Source/WebCore/platform/mediastream/mac/AVCaptureDeviceManager.mm        2016-10-18 14:53:06 UTC (rev 207463)
</span><span class="lines">@@ -174,7 +174,6 @@
</span><span class="cx">             //    application restarts, and reboots, so it could be used to figerprint a user.
</span><span class="cx">             captureDevice.m_persistentDeviceID = platformDevice.uniqueID;
</span><span class="cx">             captureDevice.m_enabled = true;
</span><del>-            captureDevice.m_groupID = createCanonicalUUIDString();
</del><span class="cx">             captureDevice.m_localizedName = platformDevice.localizedName;
</span><span class="cx">             if ([platformDevice position] == AVCaptureDevicePositionFront)
</span><span class="cx">                 captureDevice.m_position = RealtimeMediaSourceSettings::User;
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformmediastreammacRealtimeMediaSourceCenterMaccpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/mediastream/mac/RealtimeMediaSourceCenterMac.cpp (207462 => 207463)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/mediastream/mac/RealtimeMediaSourceCenterMac.cpp        2016-10-18 13:15:40 UTC (rev 207462)
+++ trunk/Source/WebCore/platform/mediastream/mac/RealtimeMediaSourceCenterMac.cpp        2016-10-18 14:53:06 UTC (rev 207463)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2013 Apple, Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2013-2016 Apple, Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -34,7 +34,6 @@
</span><span class="cx"> #include &quot;RealtimeMediaSourceCenterMac.h&quot;
</span><span class="cx"> 
</span><span class="cx"> #include &quot;AVCaptureDeviceManager.h&quot;
</span><del>-#include &quot;MediaStreamCreationClient.h&quot;
</del><span class="cx"> #include &quot;MediaStreamPrivate.h&quot;
</span><span class="cx"> #include &lt;wtf/MainThread.h&gt;
</span><span class="cx"> 
</span><span class="lines">@@ -66,10 +65,8 @@
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void RealtimeMediaSourceCenterMac::validateRequestConstraints(MediaStreamCreationClient* client, MediaConstraints&amp; audioConstraints, MediaConstraints&amp; videoConstraints)
</del><ins>+void RealtimeMediaSourceCenterMac::validateRequestConstraints(ValidConstraintsHandler validHandler, InvalidConstraintsHandler invalidHandler, MediaConstraints&amp; audioConstraints, MediaConstraints&amp; videoConstraints)
</ins><span class="cx"> {
</span><del>-    ASSERT(client);
-
</del><span class="cx">     Vector&lt;RefPtr&lt;RealtimeMediaSource&gt;&gt; audioSources;
</span><span class="cx">     Vector&lt;RefPtr&lt;RealtimeMediaSource&gt;&gt; videoSources;
</span><span class="cx"> 
</span><span class="lines">@@ -77,7 +74,7 @@
</span><span class="cx">         String invalidConstraint;
</span><span class="cx">         AVCaptureDeviceManager::singleton().verifyConstraintsForMediaType(RealtimeMediaSource::Audio, audioConstraints, nullptr, invalidConstraint);
</span><span class="cx">         if (!invalidConstraint.isEmpty()) {
</span><del>-            client-&gt;constraintsInvalid(invalidConstraint);
</del><ins>+            invalidHandler(invalidConstraint);
</ins><span class="cx">             return;
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="lines">@@ -88,60 +85,18 @@
</span><span class="cx">         String invalidConstraint;
</span><span class="cx">         AVCaptureDeviceManager::singleton().verifyConstraintsForMediaType(RealtimeMediaSource::Video, videoConstraints, nullptr, invalidConstraint);
</span><span class="cx">         if (!invalidConstraint.isEmpty()) {
</span><del>-            client-&gt;constraintsInvalid(invalidConstraint);
</del><ins>+            invalidHandler(invalidConstraint);
</ins><span class="cx">             return;
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         videoSources = AVCaptureDeviceManager::singleton().bestSourcesForTypeAndConstraints(RealtimeMediaSource::Type::Video, videoConstraints);
</span><span class="cx">     }
</span><del>-    client-&gt;constraintsValidated(audioSources, videoSources);
-}
</del><span class="cx"> 
</span><del>-void RealtimeMediaSourceCenterMac::createMediaStream(PassRefPtr&lt;MediaStreamCreationClient&gt; prpQueryClient, MediaConstraints&amp; audioConstraints, MediaConstraints&amp; videoConstraints)
-{
-    RefPtr&lt;MediaStreamCreationClient&gt; client = prpQueryClient;
-    
-    ASSERT(client);
-    
-    Vector&lt;RefPtr&lt;RealtimeMediaSource&gt;&gt; audioSources;
-    Vector&lt;RefPtr&lt;RealtimeMediaSource&gt;&gt; videoSources;
-    
-    if (audioConstraints.isValid()) {
-        String invalidConstraint;
-        AVCaptureDeviceManager::singleton().verifyConstraintsForMediaType(RealtimeMediaSource::Audio, audioConstraints, nullptr, invalidConstraint);
-        if (!invalidConstraint.isEmpty()) {
-            client-&gt;failedToCreateStreamWithConstraintsError(invalidConstraint);
-            return;
-        }
-        // FIXME: Consider the constraints when choosing among multiple devices. For now just select the first available
-        // device of the appropriate type.
-        auto audioSource = AVCaptureDeviceManager::singleton().bestSourcesForTypeAndConstraints(RealtimeMediaSource::Audio, audioConstraints).at(0);
-        ASSERT(audioSource);
-        
-        audioSources.append(WTFMove(audioSource));
-    }
-    
-    if (videoConstraints.isValid()) {
-        String invalidConstraint;
-        AVCaptureDeviceManager::singleton().verifyConstraintsForMediaType(RealtimeMediaSource::Video, videoConstraints, nullptr, invalidConstraint);
-        if (!invalidConstraint.isEmpty()) {
-            client-&gt;failedToCreateStreamWithConstraintsError(invalidConstraint);
-            return;
-        }
-        // FIXME: Consider the constraints when choosing among multiple devices. For now just select the first available
-        // device of the appropriate type.
-        auto videoSource = AVCaptureDeviceManager::singleton().bestSourcesForTypeAndConstraints(RealtimeMediaSource::Video, videoConstraints).at(0);
-        ASSERT(videoSource);
-        
-        videoSources.append(WTFMove(videoSource));
-    }
-    
-    client-&gt;didCreateStream(MediaStreamPrivate::create(audioSources, videoSources));
</del><ins>+    validHandler(WTFMove(audioSources), WTFMove(videoSources));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-void RealtimeMediaSourceCenterMac::createMediaStream(MediaStreamCreationClient* client, const String&amp; audioDeviceID, const String&amp; videoDeviceID)
</del><ins>+void RealtimeMediaSourceCenterMac::createMediaStream(NewMediaStreamHandler completionHandler, const String&amp; audioDeviceID, const String&amp; videoDeviceID)
</ins><span class="cx"> {
</span><del>-    ASSERT(client);
</del><span class="cx">     Vector&lt;RefPtr&lt;RealtimeMediaSource&gt;&gt; audioSources;
</span><span class="cx">     Vector&lt;RefPtr&lt;RealtimeMediaSource&gt;&gt; videoSources;
</span><span class="cx"> 
</span><span class="lines">@@ -156,7 +111,10 @@
</span><span class="cx">             videoSources.append(WTFMove(videoSource));
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    client-&gt;didCreateStream(MediaStreamPrivate::create(audioSources, videoSources));
</del><ins>+    if (videoSources.isEmpty() &amp;&amp; audioSources.isEmpty())
+        completionHandler(nullptr);
+    else
+        completionHandler(MediaStreamPrivate::create(audioSources, videoSources));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> Vector&lt;CaptureDevice&gt; RealtimeMediaSourceCenterMac::getMediaStreamDevices()
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformmediastreammacRealtimeMediaSourceCenterMach"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/mediastream/mac/RealtimeMediaSourceCenterMac.h (207462 => 207463)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/mediastream/mac/RealtimeMediaSourceCenterMac.h        2016-10-18 13:15:40 UTC (rev 207462)
+++ trunk/Source/WebCore/platform/mediastream/mac/RealtimeMediaSourceCenterMac.h        2016-10-18 14:53:06 UTC (rev 207463)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2013 Apple, Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2013-2016 Apple, Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -47,9 +47,8 @@
</span><span class="cx"> private:
</span><span class="cx">     ~RealtimeMediaSourceCenterMac();
</span><span class="cx"> 
</span><del>-    void validateRequestConstraints(MediaStreamCreationClient*, MediaConstraints&amp; audioConstraints, MediaConstraints&amp; videoConstraints) final;
-    void createMediaStream(PassRefPtr&lt;MediaStreamCreationClient&gt;, MediaConstraints&amp; audioConstraints, MediaConstraints&amp; videoConstraints) final;
-    void createMediaStream(MediaStreamCreationClient*, const String&amp; audioDeviceID, const String&amp; videoDeviceID) final;
</del><ins>+    void validateRequestConstraints(ValidConstraintsHandler validHandler, InvalidConstraintsHandler invalidHandler, MediaConstraints&amp; audioConstraints, MediaConstraints&amp; videoConstraints) final;
+    void createMediaStream(NewMediaStreamHandler, const String&amp; audioDeviceID, const String&amp; videoDeviceID) final;
</ins><span class="cx">     Vector&lt;CaptureDevice&gt; getMediaStreamDevices() final;
</span><span class="cx"> };
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformmediastreamopenwebrtcRealtimeMediaSourceCenterOwrcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/mediastream/openwebrtc/RealtimeMediaSourceCenterOwr.cpp (207462 => 207463)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/mediastream/openwebrtc/RealtimeMediaSourceCenterOwr.cpp        2016-10-18 13:15:40 UTC (rev 207462)
+++ trunk/Source/WebCore/platform/mediastream/openwebrtc/RealtimeMediaSourceCenterOwr.cpp        2016-10-18 14:53:06 UTC (rev 207463)
</span><span class="lines">@@ -37,7 +37,6 @@
</span><span class="cx"> #include &quot;RealtimeMediaSourceCenterOwr.h&quot;
</span><span class="cx"> 
</span><span class="cx"> #include &quot;CaptureDevice.h&quot;
</span><del>-#include &quot;MediaStreamCreationClient.h&quot;
</del><span class="cx"> #include &quot;MediaStreamPrivate.h&quot;
</span><span class="cx"> #include &quot;NotImplemented.h&quot;
</span><span class="cx"> #include &quot;OpenWebRTCUtilities.h&quot;
</span><span class="lines">@@ -77,9 +76,10 @@
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void RealtimeMediaSourceCenterOwr::validateRequestConstraints(MediaStreamCreationClient* client, MediaConstraints&amp; audioConstraints, MediaConstraints&amp; videoConstraints)
</del><ins>+void RealtimeMediaSourceCenterOwr::validateRequestConstraints(ValidConstraintsHandler validHandler, InvalidConstraintsHandler invalidHandler, MediaConstraints&amp; audioConstraints, MediaConstraints&amp; videoConstraints)
</ins><span class="cx"> {
</span><del>-    m_client = client;
</del><ins>+    m_validConstraintsHandler = WTFMove(validHandler);
+    m_invalidConstraintsHandler = WTFMove(invalidHandler);
</ins><span class="cx"> 
</span><span class="cx">     // FIXME: Actually do constraints validation. The MediaConstraints
</span><span class="cx">     // need to comply with the available audio/video device(s)
</span><span class="lines">@@ -93,46 +93,11 @@
</span><span class="cx">     owr_get_capture_sources(static_cast&lt;OwrMediaType&gt;(types), mediaSourcesAvailableCallback, this);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void RealtimeMediaSourceCenterOwr::createMediaStream(PassRefPtr&lt;MediaStreamCreationClient&gt; prpQueryClient, MediaConstraints&amp; audioConstraints, MediaConstraints&amp; videoConstraints)
</del><ins>+void RealtimeMediaSourceCenterOwr::createMediaStream(NewMediaStreamHandler completionHandler, const String&amp; audioDeviceID, const String&amp; videoDeviceID)
</ins><span class="cx"> {
</span><del>-    RefPtr&lt;MediaStreamCreationClient&gt; client = prpQueryClient;
-    ASSERT(client);
-
-    UNUSED_PARAM(audioConstraints);
-    UNUSED_PARAM(videoConstraints);
-
</del><span class="cx">     Vector&lt;RefPtr&lt;RealtimeMediaSource&gt;&gt; audioSources;
</span><span class="cx">     Vector&lt;RefPtr&lt;RealtimeMediaSource&gt;&gt; videoSources;
</span><span class="cx"> 
</span><del>-    if (audioConstraints.isValid()) {
-        // TODO: verify constraints according to registered
-        // sources. For now, unconditionally pick the first source, see bug #123345.
-        RefPtr&lt;RealtimeMediaSource&gt; audioSource = firstSource(RealtimeMediaSource::Audio);
-        if (audioSource) {
-            audioSource-&gt;reset();
-            audioSources.append(audioSource.release());
-        }
-    }
-
-    if (videoConstraints.isValid()) {
-        // TODO: verify constraints according to registered
-        // sources. For now, unconditionally pick the first source, see bug #123345.
-        RefPtr&lt;RealtimeMediaSource&gt; videoSource = firstSource(RealtimeMediaSource::Video);
-        if (videoSource) {
-            videoSource-&gt;reset();
-            videoSources.append(videoSource.release());
-        }
-    }
-
-    client-&gt;didCreateStream(MediaStreamPrivate::create(audioSources, videoSources));
-}
-
-void RealtimeMediaSourceCenterOwr::createMediaStream(MediaStreamCreationClient* client, const String&amp; audioDeviceID, const String&amp; videoDeviceID)
-{
-    ASSERT(client);
-    Vector&lt;RefPtr&lt;RealtimeMediaSource&gt;&gt; audioSources;
-    Vector&lt;RefPtr&lt;RealtimeMediaSource&gt;&gt; videoSources;
-
</del><span class="cx">     if (!audioDeviceID.isEmpty()) {
</span><span class="cx">         RealtimeMediaSourceOwrMap::iterator sourceIterator = m_sourceMap.find(audioDeviceID);
</span><span class="cx">         if (sourceIterator != m_sourceMap.end()) {
</span><span class="lines">@@ -150,7 +115,10 @@
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    client-&gt;didCreateStream(MediaStreamPrivate::create(audioSources, videoSources));
</del><ins>+    if (videoSources.isEmpty() &amp;&amp; audioSources.isEmpty())
+        completionHandler(nullptr);
+    else
+        completionHandler(MediaStreamPrivate::create(audioSources, videoSources));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> Vector&lt;CaptureDevice&gt; RealtimeMediaSourceCenterOwr::getMediaStreamDevices()
</span><span class="lines">@@ -196,7 +164,9 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     // TODO: Make sure contraints are actually validated by checking source types.
</span><del>-    m_client-&gt;constraintsValidated(audioSources, videoSources);
</del><ins>+    m_validConstraintsHandler(WTFMove(audioSources), WTFMove(videoSources));
+    m_validConstraintsHandler = nullptr;
+    m_invalidConstraintsHandler = nullptr;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> PassRefPtr&lt;RealtimeMediaSource&gt; RealtimeMediaSourceCenterOwr::firstSource(RealtimeMediaSource::Type type)
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformmediastreamopenwebrtcRealtimeMediaSourceCenterOwrh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/mediastream/openwebrtc/RealtimeMediaSourceCenterOwr.h (207462 => 207463)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/mediastream/openwebrtc/RealtimeMediaSourceCenterOwr.h        2016-10-18 13:15:40 UTC (rev 207462)
+++ trunk/Source/WebCore/platform/mediastream/openwebrtc/RealtimeMediaSourceCenterOwr.h        2016-10-18 14:53:06 UTC (rev 207463)
</span><span class="lines">@@ -54,10 +54,9 @@
</span><span class="cx">     RealtimeMediaSourceCenterOwr();
</span><span class="cx">     ~RealtimeMediaSourceCenterOwr();
</span><span class="cx"> 
</span><del>-    void validateRequestConstraints(MediaStreamCreationClient*, MediaConstraints&amp; audioConstraints, MediaConstraints&amp; videoConstraints) final;
</del><ins>+    void validateRequestConstraints(ValidConstraintsHandler validHandler, InvalidConstraintsHandler invalidHandler, MediaConstraints&amp; audioConstraints, MediaConstraints&amp; videoConstraints) final;
</ins><span class="cx"> 
</span><del>-    void createMediaStream(PassRefPtr&lt;MediaStreamCreationClient&gt;, MediaConstraints&amp; audioConstraints, MediaConstraints&amp; videoConstraints) final;
-    void createMediaStream(MediaStreamCreationClient*, const String&amp; audioDeviceID, const String&amp; videoDeviceID) final;
</del><ins>+    void createMediaStream(NewMediaStreamHandler, const String&amp; audioDeviceID, const String&amp; videoDeviceID) final;
</ins><span class="cx"> 
</span><span class="cx">     Vector&lt;CaptureDevice&gt; getMediaStreamDevices() final;
</span><span class="cx"> 
</span><span class="lines">@@ -66,7 +65,8 @@
</span><span class="cx"> private:
</span><span class="cx">     PassRefPtr&lt;RealtimeMediaSource&gt; firstSource(RealtimeMediaSource::Type);
</span><span class="cx">     RealtimeMediaSourceOwrMap m_sourceMap;
</span><del>-    RefPtr&lt;MediaStreamCreationClient&gt; m_client;
</del><ins>+    ValidConstraintsHandler m_validConstraintsHandler;
+    InvalidConstraintsHandler m_invalidConstraintsHandler;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformmockMockRealtimeMediaSourceCentercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/mock/MockRealtimeMediaSourceCenter.cpp (207462 => 207463)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/mock/MockRealtimeMediaSourceCenter.cpp        2016-10-18 13:15:40 UTC (rev 207462)
+++ trunk/Source/WebCore/platform/mock/MockRealtimeMediaSourceCenter.cpp        2016-10-18 14:53:06 UTC (rev 207463)
</span><span class="lines">@@ -33,7 +33,6 @@
</span><span class="cx"> #include &quot;CaptureDevice.h&quot;
</span><span class="cx"> #include &quot;MediaConstraintsMock.h&quot;
</span><span class="cx"> #include &quot;MediaStream.h&quot;
</span><del>-#include &quot;MediaStreamCreationClient.h&quot;
</del><span class="cx"> #include &quot;MediaStreamPrivate.h&quot;
</span><span class="cx"> #include &quot;MediaStreamTrack.h&quot;
</span><span class="cx"> #include &quot;MockRealtimeAudioSource.h&quot;
</span><span class="lines">@@ -67,10 +66,8 @@
</span><span class="cx">     m_supportedConstraints.setSupportsDeviceId(true);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void MockRealtimeMediaSourceCenter::validateRequestConstraints(MediaStreamCreationClient* client, MediaConstraints&amp; audioConstraints, MediaConstraints&amp; videoConstraints)
</del><ins>+void MockRealtimeMediaSourceCenter::validateRequestConstraints(ValidConstraintsHandler validHandler, InvalidConstraintsHandler invalidHandler, MediaConstraints&amp; audioConstraints, MediaConstraints&amp; videoConstraints)
</ins><span class="cx"> {
</span><del>-    ASSERT(client);
-
</del><span class="cx">     Vector&lt;RefPtr&lt;RealtimeMediaSource&gt;&gt; audioSources;
</span><span class="cx">     Vector&lt;RefPtr&lt;RealtimeMediaSource&gt;&gt; videoSources;
</span><span class="cx"> 
</span><span class="lines">@@ -77,7 +74,7 @@
</span><span class="cx">     if (audioConstraints.isValid()) {
</span><span class="cx">         String invalidQuery = MediaConstraintsMock::verifyConstraints(RealtimeMediaSource::Audio, audioConstraints);
</span><span class="cx">         if (!invalidQuery.isEmpty()) {
</span><del>-            client-&gt;constraintsInvalid(invalidQuery);
</del><ins>+            invalidHandler(invalidQuery);
</ins><span class="cx">             return;
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="lines">@@ -88,7 +85,7 @@
</span><span class="cx">     if (videoConstraints.isValid()) {
</span><span class="cx">         String invalidQuery = MediaConstraintsMock::verifyConstraints(RealtimeMediaSource::Video, videoConstraints);
</span><span class="cx">         if (!invalidQuery.isEmpty()) {
</span><del>-            client-&gt;constraintsInvalid(invalidQuery);
</del><ins>+            invalidHandler(invalidQuery);
</ins><span class="cx">             return;
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="lines">@@ -96,61 +93,26 @@
</span><span class="cx">         videoSources.append(WTFMove(videoSource));
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    client-&gt;constraintsValidated(audioSources, videoSources);
</del><ins>+    validHandler(WTFMove(audioSources), WTFMove(videoSources));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-void MockRealtimeMediaSourceCenter::createMediaStream(PassRefPtr&lt;MediaStreamCreationClient&gt; prpQueryClient, MediaConstraints&amp; audioConstraints, MediaConstraints&amp; videoConstraints)
</del><ins>+void MockRealtimeMediaSourceCenter::createMediaStream(NewMediaStreamHandler completionHandler, const String&amp; audioDeviceID, const String&amp; videoDeviceID)
</ins><span class="cx"> {
</span><del>-    RefPtr&lt;MediaStreamCreationClient&gt; client = prpQueryClient;
-
-    ASSERT(client);
-    
</del><span class="cx">     Vector&lt;RefPtr&lt;RealtimeMediaSource&gt;&gt; audioSources;
</span><span class="cx">     Vector&lt;RefPtr&lt;RealtimeMediaSource&gt;&gt; videoSources;
</span><span class="cx"> 
</span><del>-    if (audioConstraints.isValid()) {
-        const String invalidQuery = MediaConstraintsMock::verifyConstraints(RealtimeMediaSource::Audio, audioConstraints);
-        if (!invalidQuery.isEmpty()) {
-            client-&gt;failedToCreateStreamWithConstraintsError(invalidQuery);
-            return;
-        }
</del><ins>+    if (audioDeviceID == MockRealtimeMediaSource::mockAudioSourcePersistentID())
+        audioSources.append(MockRealtimeAudioSource::create());
</ins><span class="cx"> 
</span><del>-        auto audioSource = MockRealtimeAudioSource::create();
-        audioSources.append(WTFMove(audioSource));
-    }
</del><ins>+    if (videoDeviceID == MockRealtimeMediaSource::mockVideoSourcePersistentID())
+        videoSources.append(MockRealtimeVideoSource::create());
</ins><span class="cx"> 
</span><del>-    if (videoConstraints.isValid()) {
-        const String invalidQuery = MediaConstraintsMock::verifyConstraints(RealtimeMediaSource::Video, videoConstraints);
-        if (!invalidQuery.isEmpty()) {
-            client-&gt;failedToCreateStreamWithConstraintsError(invalidQuery);
-            return;
-        }
-
-        auto videoSource = MockRealtimeVideoSource::create();
-        videoSources.append(WTFMove(videoSource));
-    }
-    
-    client-&gt;didCreateStream(MediaStreamPrivate::create(audioSources, videoSources));
</del><ins>+    if (videoSources.isEmpty() &amp;&amp; audioSources.isEmpty())
+        completionHandler(nullptr);
+    else
+        completionHandler(MediaStreamPrivate::create(audioSources, videoSources));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-void MockRealtimeMediaSourceCenter::createMediaStream(MediaStreamCreationClient* client, const String&amp; audioDeviceID, const String&amp; videoDeviceID)
-{
-    ASSERT(client);
-    Vector&lt;RefPtr&lt;RealtimeMediaSource&gt;&gt; audioSources;
-    Vector&lt;RefPtr&lt;RealtimeMediaSource&gt;&gt; videoSources;
-
-    if (!audioDeviceID.isEmpty() &amp;&amp; audioDeviceID == MockRealtimeMediaSource::mockAudioSourcePersistentID()) {
-        auto audioSource = MockRealtimeAudioSource::create();
-        audioSources.append(WTFMove(audioSource));
-    }
-    if (!videoDeviceID.isEmpty() &amp;&amp; videoDeviceID == MockRealtimeMediaSource::mockVideoSourcePersistentID()) {
-        auto videoSource = MockRealtimeVideoSource::create();
-        videoSources.append(WTFMove(videoSource));
-    }
-
-    client-&gt;didCreateStream(MediaStreamPrivate::create(audioSources, videoSources));
-}
-
</del><span class="cx"> Vector&lt;CaptureDevice&gt; MockRealtimeMediaSourceCenter::getMediaStreamDevices()
</span><span class="cx"> {
</span><span class="cx">     Vector&lt;CaptureDevice&gt; sources;
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformmockMockRealtimeMediaSourceCenterh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/mock/MockRealtimeMediaSourceCenter.h (207462 => 207463)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/mock/MockRealtimeMediaSourceCenter.h        2016-10-18 13:15:40 UTC (rev 207462)
+++ trunk/Source/WebCore/platform/mock/MockRealtimeMediaSourceCenter.h        2016-10-18 14:53:06 UTC (rev 207463)
</span><span class="lines">@@ -41,10 +41,9 @@
</span><span class="cx">     friend NeverDestroyed&lt;MockRealtimeMediaSourceCenter&gt;;
</span><span class="cx">     MockRealtimeMediaSourceCenter();
</span><span class="cx"> 
</span><del>-    void validateRequestConstraints(MediaStreamCreationClient*, MediaConstraints&amp; audioConstraints, MediaConstraints&amp; videoConstraints) override;
-    void createMediaStream(PassRefPtr&lt;MediaStreamCreationClient&gt;, MediaConstraints&amp; audioConstraints, MediaConstraints&amp; videoConstraints) override;
</del><ins>+    void validateRequestConstraints(ValidConstraintsHandler validHandler, InvalidConstraintsHandler invalidHandler, MediaConstraints&amp; audioConstraints, MediaConstraints&amp; videoConstraints) override;
</ins><span class="cx">     Vector&lt;CaptureDevice&gt; getMediaStreamDevices() override;
</span><del>-    void createMediaStream(MediaStreamCreationClient*, const String&amp; audioDeviceID, const String&amp; videoDeviceID) override;
</del><ins>+    void createMediaStream(NewMediaStreamHandler, const String&amp; audioDeviceID, const String&amp; videoDeviceID) override;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebKitmacChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/mac/ChangeLog (207462 => 207463)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/mac/ChangeLog        2016-10-18 13:15:40 UTC (rev 207462)
+++ trunk/Source/WebKit/mac/ChangeLog        2016-10-18 14:53:06 UTC (rev 207463)
</span><span class="lines">@@ -1,3 +1,30 @@
</span><ins>+2016-10-18  Eric Carlson  &lt;eric.carlson@apple.com&gt;
+
+        [MediaStream] Resolve constraints and enumerate devices in the UI process
+        https://bugs.webkit.org/show_bug.cgi?id=162147
+        &lt;rdar://problem/28803569&gt;
+
+        Reviewed by Darin Adler.
+
+        * WebCoreSupport/WebUserMediaClient.h:
+        * WebCoreSupport/WebUserMediaClient.mm:
+        (AddPermissionCheckToMap):
+        (RemovePermissionCheckFromMap):
+        (WebUserMediaClient::pageDestroyed):
+        (WebUserMediaClient::requestUserMediaAccess):
+        (WebUserMediaClient::enumerateMediaDevices):
+        (WebUserMediaClient::cancelMediaDevicesEnumerationRequest):
+        (-[WebUserMediaPolicyListener allow]):
+        (-[WebUserMediaPolicyListener deny]):
+        (-[WebUserMediaPolicyCheckerListener initWithMediaDevicesEnumerationRequest:]):
+        (-[WebUserMediaPolicyCheckerListener cancelMediaDevicesEnumerationRequest]):
+        (-[WebUserMediaPolicyCheckerListener allow]):
+        (-[WebUserMediaPolicyCheckerListener deny]):
+        (WebUserMediaClient::checkUserMediaPermission): Deleted.
+        (WebUserMediaClient::cancelUserMediaPermissionCheck): Deleted.
+        (-[WebUserMediaPolicyCheckerListener initWithUserMediaPermissionCheck:]): Deleted.
+        (-[WebUserMediaPolicyCheckerListener cancelUserMediaPermissionCheck]): Deleted.
+
</ins><span class="cx"> 2016-10-17  Antti Koivisto  &lt;antti@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Rename setNeedsStyleRecalc to invalidateStyle
</span></span></pre></div>
<a id="trunkSourceWebKitmacWebCoreSupportWebUserMediaClienth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/mac/WebCoreSupport/WebUserMediaClient.h (207462 => 207463)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/mac/WebCoreSupport/WebUserMediaClient.h        2016-10-18 13:15:40 UTC (rev 207462)
+++ trunk/Source/WebKit/mac/WebCoreSupport/WebUserMediaClient.h        2016-10-18 14:53:06 UTC (rev 207463)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2013 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2013-2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -30,12 +30,6 @@
</span><span class="cx"> 
</span><span class="cx"> #import &lt;WebCore/UserMediaClient.h&gt;
</span><span class="cx"> 
</span><del>-namespace WebCore {
-class UserMediaClient;
-class UserMediaPermissionCheck;
-class UserMediaRequest;
-}
-
</del><span class="cx"> @class WebView;
</span><span class="cx"> 
</span><span class="cx"> class WebUserMediaClient final : public WebCore::UserMediaClient {
</span><span class="lines">@@ -44,13 +38,13 @@
</span><span class="cx">     ~WebUserMediaClient();
</span><span class="cx"> 
</span><span class="cx">     // UserMediaClient
</span><del>-    void requestUserMediaAccess(WebCore::UserMediaRequest&amp;) override;
-    void cancelUserMediaAccessRequest(WebCore::UserMediaRequest&amp;) override;
</del><ins>+    void requestUserMediaAccess(WebCore::UserMediaRequest&amp;) final;
+    void cancelUserMediaAccessRequest(WebCore::UserMediaRequest&amp;) final;
</ins><span class="cx"> 
</span><del>-    void checkUserMediaPermission(WebCore::UserMediaPermissionCheck&amp;) override;
-    void cancelUserMediaPermissionCheck(WebCore::UserMediaPermissionCheck&amp;) override;
</del><ins>+    void enumerateMediaDevices(WebCore::MediaDevicesEnumerationRequest&amp;) final;
+    void cancelMediaDevicesEnumerationRequest(WebCore::MediaDevicesEnumerationRequest&amp;) final;
</ins><span class="cx"> 
</span><del>-    void pageDestroyed() override;
</del><ins>+    void pageDestroyed() final;
</ins><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     WebView* m_webView;
</span></span></pre></div>
<a id="trunkSourceWebKitmacWebCoreSupportWebUserMediaClientmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/mac/WebCoreSupport/WebUserMediaClient.mm (207462 => 207463)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/mac/WebCoreSupport/WebUserMediaClient.mm        2016-10-18 13:15:40 UTC (rev 207462)
+++ trunk/Source/WebKit/mac/WebCoreSupport/WebUserMediaClient.mm        2016-10-18 14:53:06 UTC (rev 207463)
</span><span class="lines">@@ -31,9 +31,11 @@
</span><span class="cx"> #import &quot;WebSecurityOriginInternal.h&quot;
</span><span class="cx"> #import &quot;WebUIDelegatePrivate.h&quot;
</span><span class="cx"> #import &quot;WebViewInternal.h&quot;
</span><ins>+#import &lt;WebCore/CaptureDevice.h&gt;
+#import &lt;WebCore/MediaDevicesEnumerationRequest.h&gt;
</ins><span class="cx"> #import &lt;WebCore/Page.h&gt;
</span><ins>+#import &lt;WebCore/RealtimeMediaSourceCenter.h&gt;
</ins><span class="cx"> #import &lt;WebCore/ScriptExecutionContext.h&gt;
</span><del>-#import &lt;WebCore/UserMediaPermissionCheck.h&gt;
</del><span class="cx"> #import &lt;WebCore/UserMediaRequest.h&gt;
</span><span class="cx"> #import &lt;wtf/BlockObjCExceptions.h&gt;
</span><span class="cx"> #import &lt;wtf/HashMap.h&gt;
</span><span class="lines">@@ -53,10 +55,10 @@
</span><span class="cx"> @end
</span><span class="cx"> 
</span><span class="cx"> @interface WebUserMediaPolicyCheckerListener : NSObject &lt;WebAllowDenyPolicyListener&gt; {
</span><del>-    RefPtr&lt;UserMediaPermissionCheck&gt; _request;
</del><ins>+    RefPtr&lt;MediaDevicesEnumerationRequest&gt; _request;
</ins><span class="cx"> }
</span><del>-- (id)initWithUserMediaPermissionCheck:(PassRefPtr&lt;UserMediaPermissionCheck&gt;)request;
-- (void)cancelUserMediaPermissionCheck;
</del><ins>+- (id)initWithMediaDevicesEnumerationRequest:(PassRefPtr&lt;MediaDevicesEnumerationRequest&gt;)request;
+- (void)cancelMediaDevicesEnumerationRequest;
</ins><span class="cx"> - (void)deny;
</span><span class="cx"> @end
</span><span class="cx"> 
</span><span class="lines">@@ -78,7 +80,7 @@
</span><span class="cx">     userMediaRequestsMap().remove(request);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-typedef HashMap&lt;RefPtr&lt;UserMediaPermissionCheck&gt;, RetainPtr&lt;WebUserMediaPolicyCheckerListener&gt;&gt; UserMediaCheckMap;
</del><ins>+typedef HashMap&lt;RefPtr&lt;MediaDevicesEnumerationRequest&gt;, RetainPtr&lt;WebUserMediaPolicyCheckerListener&gt;&gt; UserMediaCheckMap;
</ins><span class="cx"> 
</span><span class="cx"> static UserMediaCheckMap&amp; userMediaCheckMap()
</span><span class="cx"> {
</span><span class="lines">@@ -86,12 +88,12 @@
</span><span class="cx">     return requests;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static void AddPermissionCheckToMap(UserMediaPermissionCheck* request, RetainPtr&lt;WebUserMediaPolicyCheckerListener&gt; listener)
</del><ins>+static void AddPermissionCheckToMap(MediaDevicesEnumerationRequest* request, RetainPtr&lt;WebUserMediaPolicyCheckerListener&gt; listener)
</ins><span class="cx"> {
</span><span class="cx">     userMediaCheckMap().set(request, listener);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static void RemovePermissionCheckFromMap(UserMediaPermissionCheck* request)
</del><ins>+static void RemovePermissionCheckFromMap(MediaDevicesEnumerationRequest* request)
</ins><span class="cx"> {
</span><span class="cx">     userMediaCheckMap().remove(request);
</span><span class="cx"> }
</span><span class="lines">@@ -123,7 +125,7 @@
</span><span class="cx">     checkMap.clear();
</span><span class="cx"> 
</span><span class="cx">     for (auto&amp; check : pendingChecks)
</span><del>-        [check cancelUserMediaPermissionCheck];
</del><ins>+        [check cancelMediaDevicesEnumerationRequest];
</ins><span class="cx"> 
</span><span class="cx">     ASSERT(userMediaCheckMap().isEmpty());
</span><span class="cx"> 
</span><span class="lines">@@ -136,7 +138,7 @@
</span><span class="cx"> 
</span><span class="cx">     SEL selector = @selector(webView:decidePolicyForUserMediaRequestFromOrigin:listener:);
</span><span class="cx">     if (![[m_webView UIDelegate] respondsToSelector:selector]) {
</span><del>-        request.userMediaAccessDenied();
</del><ins>+        request.deny(UserMediaRequest::MediaAccessDenialReason::UserMediaDisabled, &quot;&quot;);
</ins><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -163,17 +165,17 @@
</span><span class="cx">     requestsMap.remove(it);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void WebUserMediaClient::checkUserMediaPermission(UserMediaPermissionCheck&amp; request)
</del><ins>+void WebUserMediaClient::enumerateMediaDevices(MediaDevicesEnumerationRequest&amp; request)
</ins><span class="cx"> {
</span><span class="cx">     BEGIN_BLOCK_OBJC_EXCEPTIONS;
</span><span class="cx"> 
</span><span class="cx">     SEL selector = @selector(webView:checkPolicyForUserMediaRequestFromOrigin:listener:);
</span><span class="cx">     if (![[m_webView UIDelegate] respondsToSelector:selector]) {
</span><del>-        request.setUserMediaAccessInfo(emptyString(), false);
</del><ins>+        request.setDeviceInfo(Vector&lt;CaptureDevice&gt;(), emptyString(), false);
</ins><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    WebUserMediaPolicyCheckerListener *listener = [[WebUserMediaPolicyCheckerListener alloc] initWithUserMediaPermissionCheck:&amp;request];
</del><ins>+    WebUserMediaPolicyCheckerListener *listener = [[WebUserMediaPolicyCheckerListener alloc] initWithMediaDevicesEnumerationRequest:&amp;request];
</ins><span class="cx">     WebSecurityOrigin *webOrigin = [[WebSecurityOrigin alloc] _initWithWebCoreSecurityOrigin:request.userMediaDocumentOrigin()];
</span><span class="cx"> 
</span><span class="cx">     AddPermissionCheckToMap(&amp;request, listener);
</span><span class="lines">@@ -185,7 +187,7 @@
</span><span class="cx">     END_BLOCK_OBJC_EXCEPTIONS;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void WebUserMediaClient::cancelUserMediaPermissionCheck(WebCore::UserMediaPermissionCheck&amp; request)
</del><ins>+void WebUserMediaClient::cancelMediaDevicesEnumerationRequest(WebCore::MediaDevicesEnumerationRequest&amp; request)
</ins><span class="cx"> {
</span><span class="cx">     UserMediaCheckMap&amp; requestsMap = userMediaCheckMap();
</span><span class="cx">     UserMediaCheckMap::iterator it = requestsMap.find(&amp;request);
</span><span class="lines">@@ -192,7 +194,7 @@
</span><span class="cx">     if (it == requestsMap.end())
</span><span class="cx">         return;
</span><span class="cx"> 
</span><del>-    [it-&gt;value cancelUserMediaPermissionCheck];
</del><ins>+    [it-&gt;value cancelMediaDevicesEnumerationRequest];
</ins><span class="cx">     requestsMap.remove(it);
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -226,7 +228,7 @@
</span><span class="cx">     if (!_request)
</span><span class="cx">         return;
</span><span class="cx">     
</span><del>-    _request-&gt;userMediaAccessGranted(_request-&gt;allowedAudioDeviceUID(), _request-&gt;allowedVideoDeviceUID());
</del><ins>+    // FIXME: https://bugs.webkit.org/show_bug.cgi?id=162154
</ins><span class="cx">     RemoveRequestFromRequestMap(_request.get());
</span><span class="cx"> #endif
</span><span class="cx"> }
</span><span class="lines">@@ -237,7 +239,7 @@
</span><span class="cx">     if (!_request)
</span><span class="cx">         return;
</span><span class="cx">     
</span><del>-    _request-&gt;userMediaAccessDenied();
</del><ins>+    // FIXME: https://bugs.webkit.org/show_bug.cgi?id=162154
</ins><span class="cx">     RemoveRequestFromRequestMap(_request.get());
</span><span class="cx"> #endif
</span><span class="cx"> }
</span><span class="lines">@@ -260,7 +262,7 @@
</span><span class="cx"> 
</span><span class="cx"> @implementation WebUserMediaPolicyCheckerListener
</span><span class="cx"> 
</span><del>-- (id)initWithUserMediaPermissionCheck:(PassRefPtr&lt;UserMediaPermissionCheck&gt;)request
</del><ins>+- (id)initWithMediaDevicesEnumerationRequest:(PassRefPtr&lt;MediaDevicesEnumerationRequest&gt;)request
</ins><span class="cx"> {
</span><span class="cx"> #if ENABLE(MEDIA_STREAM)
</span><span class="cx">     if (!(self = [super init]))
</span><span class="lines">@@ -271,7 +273,7 @@
</span><span class="cx"> #endif
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-- (void)cancelUserMediaPermissionCheck
</del><ins>+- (void)cancelMediaDevicesEnumerationRequest
</ins><span class="cx"> {
</span><span class="cx"> #if ENABLE(MEDIA_STREAM)
</span><span class="cx">     if (!_request)
</span><span class="lines">@@ -288,7 +290,7 @@
</span><span class="cx">     if (!_request)
</span><span class="cx">         return;
</span><span class="cx"> 
</span><del>-    _request-&gt;setUserMediaAccessInfo(_request-&gt;mediaDeviceIdentifierHashSalt(), true);
</del><ins>+    // FIXME: https://bugs.webkit.org/show_bug.cgi?id=162154
</ins><span class="cx">     RemovePermissionCheckFromMap(_request.get());
</span><span class="cx"> #endif
</span><span class="cx"> }
</span><span class="lines">@@ -299,7 +301,7 @@
</span><span class="cx">     if (!_request)
</span><span class="cx">         return;
</span><span class="cx"> 
</span><del>-    _request-&gt;setUserMediaAccessInfo(emptyString(), true);
</del><ins>+    // FIXME: https://bugs.webkit.org/show_bug.cgi?id=162154
</ins><span class="cx">     RemovePermissionCheckFromMap(_request.get());
</span><span class="cx"> #endif
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebKit2ChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/ChangeLog (207462 => 207463)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/ChangeLog        2016-10-18 13:15:40 UTC (rev 207462)
+++ trunk/Source/WebKit2/ChangeLog        2016-10-18 14:53:06 UTC (rev 207463)
</span><span class="lines">@@ -1,3 +1,92 @@
</span><ins>+2016-10-18  Eric Carlson  &lt;eric.carlson@apple.com&gt;
+
+        [MediaStream] Resolve constraints and enumerate devices in the UI process
+        https://bugs.webkit.org/show_bug.cgi?id=162147
+        &lt;rdar://problem/28803569&gt;
+
+        Reviewed by Darin Adler.
+        
+        Restructure gUM constraint validation and MediaDevices.enumerateDevices so all media device
+        access happens in the UI process.
+
+        * Scripts/webkit/messages.py:
+        (headers_for_type): Special case MediaConstraintsData.
+
+        * Shared/WebCoreArgumentCoders.cpp:
+        (IPC::encodeMediaTrackConstraintSetMap): MediaTrackConstraintSetMap encoder.
+        (IPC::ArgumentCoder&lt;MediaConstraintsData&gt;::encode): MediaConstraintsData encoder.
+        (IPC::decodeMediaTrackConstraintSetMap): MediaTrackConstraintSetMap decoder.
+        (IPC::ArgumentCoder&lt;MediaConstraintsData&gt;::decode): MediaConstraintsData decoder.
+        (IPC::ArgumentCoder&lt;CaptureDevice&gt;::encode): CaptureDevice enoder.
+        (IPC::ArgumentCoder&lt;CaptureDevice&gt;::decode): CaptureDevice decoder.
+        * Shared/WebCoreArgumentCoders.h:
+
+        * UIProcess/API/APIUIClient.h:  Remove UserMediaPermissionCheckProxy forward declaration.
+
+        * UIProcess/API/C/WKUserMediaPermissionRequest.cpp:
+        (toWK): Translate UserMediaPermissionRequestDenialReason to UserMediaAccessDenialReason.
+        (WKUserMediaPermissionRequestDeny): Add &quot;reason&quot; parameter.
+        * UIProcess/API/C/WKUserMediaPermissionRequest.h:
+
+        * UIProcess/UserMediaPermissionRequestManagerProxy.cpp:
+        (WebKit::UserMediaPermissionRequestManagerProxy::invalidateRequests): Invalidate pending device requests.
+        (WebKit::UserMediaPermissionRequestManagerProxy::createRequest): Make private.
+        (WebKit::toWebCore): Map from UserMediaAccessDenialReason to MediaAccessDenialReason, cast to
+          uint64_t to pass to web process.
+        (WebKit::UserMediaPermissionRequestManagerProxy::denyRequest): Send to web process.
+        (WebKit::UserMediaPermissionRequestManagerProxy::userMediaAccessWasGranted): Ditto.
+        (WebKit::UserMediaPermissionRequestManagerProxy::requestUserMediaPermissionForFrame): Validate
+          constraints and make sure gUM is enabled before prompting user.
+        (WebKit::UserMediaPermissionRequestManagerProxy::enumerateMediaDevicesForFrame): New.
+        (WebKit::UserMediaPermissionRequestManagerProxy::didCompleteUserMediaPermissionCheck): Send 
+          results of device enumeration to web process.
+        (WebKit::UserMediaPermissionRequestManagerProxy::didReceiveUserMediaPermissionDecision): Deleted.
+        (WebKit::UserMediaPermissionRequestManagerProxy::createUserMediaPermissionCheck): Deleted.
+        * UIProcess/UserMediaPermissionRequestManagerProxy.h:
+
+        * UIProcess/UserMediaPermissionRequestProxy.cpp:
+        (WebKit::UserMediaPermissionRequestProxy::allow):
+        (WebKit::UserMediaPermissionRequestProxy::deny): Take &quot;reason&quot; parameter.
+        * UIProcess/UserMediaPermissionRequestProxy.h:
+
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::requestUserMediaPermissionForFrame):
+        (WebKit::WebPageProxy::enumerateMediaDevicesForFrame):
+        (WebKit::WebPageProxy::checkUserMediaPermissionForFrame): Deleted.
+        * UIProcess/WebPageProxy.h:
+        * UIProcess/WebPageProxy.messages.in:
+
+        * WebProcess/MediaStream/UserMediaPermissionRequestManager.cpp:
+        (WebKit::UserMediaPermissionRequestManager::startUserMediaRequest): userMediaAccessDenied -&gt; deny.
+          Pass the audio and video constraints to the UI process.
+        (WebKit::UserMediaPermissionRequestManager::userMediaAccessWasGranted): 
+        (WebKit::UserMediaPermissionRequestManager::userMediaAccessWasDenied):
+        (WebKit::UserMediaPermissionRequestManager::enumerateMediaDevices): Send the enumeration request
+          to the UI process.
+        (WebKit::UserMediaPermissionRequestManager::cancelMediaDevicesEnumeration):
+        (WebKit::UserMediaPermissionRequestManager::didCompleteMediaDeviceEnumeration):
+        (WebKit::UserMediaPermissionRequestManager::didReceiveUserMediaPermissionDecision): Deleted.
+        (WebKit::UserMediaPermissionRequestManager::startUserMediaPermissionCheck): Deleted.
+        (WebKit::UserMediaPermissionRequestManager::cancelUserMediaPermissionCheck): Deleted.
+        (WebKit::UserMediaPermissionRequestManager::didCompleteUserMediaPermissionCheck): Deleted.
+        * WebProcess/MediaStream/UserMediaPermissionRequestManager.h:
+
+        * WebProcess/WebCoreSupport/WebUserMediaClient.cpp:
+        (WebKit::WebUserMediaClient::enumerateMediaDevices): New.
+        (WebKit::WebUserMediaClient::cancelMediaDevicesEnumerationRequest): New.
+        (WebKit::WebUserMediaClient::checkUserMediaPermission): Deleted.
+        (WebKit::WebUserMediaClient::cancelUserMediaPermissionCheck): Deleted.
+        * WebProcess/WebCoreSupport/WebUserMediaClient.h:
+
+        * WebProcess/WebPage/WebPage.cpp:
+        (WebKit::WebPage::userMediaAccessWasGranted): New.
+        (WebKit::WebPage::userMediaAccessWasDenied): Ditto.
+        (WebKit::WebPage::didCompleteMediaDeviceEnumeration):
+        (WebKit::WebPage::didReceiveUserMediaPermissionDecision): Deleted.
+        (WebKit::WebPage::didCompleteUserMediaPermissionCheck): Deleted.
+        * WebProcess/WebPage/WebPage.h:
+        * WebProcess/WebPage/WebPage.messages.in:
+
</ins><span class="cx"> 2016-10-17  Antti Koivisto  &lt;antti@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Rename setNeedsStyleRecalc to invalidateStyle
</span></span></pre></div>
<a id="trunkSourceWebKit2Scriptswebkitmessagespy"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/Scripts/webkit/messages.py (207462 => 207463)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/Scripts/webkit/messages.py        2016-10-18 13:15:40 UTC (rev 207462)
+++ trunk/Source/WebKit2/Scripts/webkit/messages.py        2016-10-18 14:53:06 UTC (rev 207463)
</span><span class="lines">@@ -355,6 +355,7 @@
</span><span class="cx">         'WebCore::Highlight': ['&lt;WebCore/InspectorOverlay.h&gt;'],
</span><span class="cx">         'WebCore::KeyframeValueList': ['&lt;WebCore/GraphicsLayer.h&gt;'],
</span><span class="cx">         'WebCore::KeypressCommand': ['&lt;WebCore/KeyboardEvent.h&gt;'],
</span><ins>+        'WebCore::MediaConstraintsData': ['&lt;WebCore/MediaConstraintsImpl.h&gt;'],
</ins><span class="cx">         'WebCore::PasteboardImage': ['&lt;WebCore/Pasteboard.h&gt;'],
</span><span class="cx">         'WebCore::PasteboardWebContent': ['&lt;WebCore/Pasteboard.h&gt;'],
</span><span class="cx">         'WebCore::PluginInfo': ['&lt;WebCore/PluginData.h&gt;'],
</span></span></pre></div>
<a id="trunkSourceWebKit2SharedWebCoreArgumentCoderscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/Shared/WebCoreArgumentCoders.cpp (207462 => 207463)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/Shared/WebCoreArgumentCoders.cpp        2016-10-18 13:15:40 UTC (rev 207462)
+++ trunk/Source/WebKit2/Shared/WebCoreArgumentCoders.cpp        2016-10-18 14:53:06 UTC (rev 207463)
</span><span class="lines">@@ -93,6 +93,11 @@
</span><span class="cx"> #include &lt;WebCore/MediaSessionMetadata.h&gt;
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+#if ENABLE(MEDIA_STREAM)
+#include &lt;WebCore/CaptureDevice.h&gt;
+#include &lt;WebCore/MediaConstraintsImpl.h&gt;
+#endif
+
</ins><span class="cx"> using namespace WebCore;
</span><span class="cx"> using namespace WebKit;
</span><span class="cx"> 
</span><span class="lines">@@ -2219,5 +2224,84 @@
</span><span class="cx">     return true;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+#if ENABLE(MEDIA_STREAM)
+void ArgumentCoder&lt;MediaConstraintsData&gt;::encode(Encoder&amp; encoder, const WebCore::MediaConstraintsData&amp; constraint)
+{
+    encoder &lt;&lt; constraint.mandatoryConstraints;
</ins><span class="cx"> 
</span><ins>+    auto&amp; advancedConstraints = constraint.advancedConstraints;
+    encoder &lt;&lt; static_cast&lt;uint64_t&gt;(advancedConstraints.size());
+    for (const auto&amp; advancedConstraint : advancedConstraints)
+        encoder &lt;&lt; advancedConstraint;
+
+    encoder &lt;&lt; constraint.isValid;
+}
+
+bool ArgumentCoder&lt;MediaConstraintsData&gt;::decode(Decoder&amp; decoder, WebCore::MediaConstraintsData&amp; constraints)
+{
+    MediaTrackConstraintSetMap mandatoryConstraints;
+    if (!decoder.decode(mandatoryConstraints))
+        return false;
+
+    uint64_t advancedCount;
+    if (!decoder.decode(advancedCount))
+        return false;
+
+    Vector&lt;MediaTrackConstraintSetMap&gt; advancedConstraints;
+    advancedConstraints.reserveInitialCapacity(advancedCount);
+    for (size_t i = 0; i &lt; advancedCount; ++i) {
+        MediaTrackConstraintSetMap map;
+        if (!decoder.decode(map))
+            return false;
+
+        advancedConstraints.uncheckedAppend(WTFMove(map));
+    }
+
+    bool isValid;
+    if (!decoder.decode(isValid))
+        return false;
+
+    constraints.mandatoryConstraints = WTFMove(mandatoryConstraints);
+    constraints.advancedConstraints = WTFMove(advancedConstraints);
+    constraints.isValid = isValid;
+
+    return true;
+}
+
+void ArgumentCoder&lt;CaptureDevice&gt;::encode(Encoder&amp; encoder, const WebCore::CaptureDevice&amp; device)
+{
+    encoder &lt;&lt; device.persistentId();
+    encoder &lt;&lt; device.label();
+    encoder &lt;&lt; device.groupId();
+    encoder.encodeEnum(device.kind());
+}
+
+bool ArgumentCoder&lt;CaptureDevice&gt;::decode(Decoder&amp; decoder, WebCore::CaptureDevice&amp; device)
+{
+    String persistentId;
+    if (!decoder.decode(persistentId))
+        return false;
+
+    String label;
+    if (!decoder.decode(label))
+        return false;
+
+    String groupId;
+    if (!decoder.decode(groupId))
+        return false;
+
+    CaptureDevice::SourceKind kind;
+    if (!decoder.decodeEnum(kind))
+        return false;
+
+    device.setPersistentId(persistentId);
+    device.setLabel(label);
+    device.setGroupId(groupId);
+    device.setKind(kind);
+
+    return true;
+}
+#endif
+
+
</ins><span class="cx"> } // namespace IPC
</span></span></pre></div>
<a id="trunkSourceWebKit2SharedWebCoreArgumentCodersh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/Shared/WebCoreArgumentCoders.h (207462 => 207463)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/Shared/WebCoreArgumentCoders.h        2016-10-18 13:15:40 UTC (rev 207462)
+++ trunk/Source/WebKit2/Shared/WebCoreArgumentCoders.h        2016-10-18 14:53:06 UTC (rev 207463)
</span><span class="lines">@@ -127,6 +127,13 @@
</span><span class="cx"> }
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+#if ENABLE(MEDIA_STREAM)
+namespace WebCore {
+class CaptureDevice;
+struct MediaConstraintsData;
+}
+#endif
+
</ins><span class="cx"> namespace IPC {
</span><span class="cx"> 
</span><span class="cx"> template&lt;&gt; struct ArgumentCoder&lt;WebCore::AffineTransform&gt; {
</span><span class="lines">@@ -528,6 +535,18 @@
</span><span class="cx"> 
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+#if ENABLE(MEDIA_STREAM)
+template&lt;&gt; struct ArgumentCoder&lt;WebCore::MediaConstraintsData&gt; {
+    static void encode(Encoder&amp;, const WebCore::MediaConstraintsData&amp;);
+    static bool decode(Decoder&amp;, WebCore::MediaConstraintsData&amp;);
+};
+
+template&lt;&gt; struct ArgumentCoder&lt;WebCore::CaptureDevice&gt; {
+    static void encode(Encoder&amp;, const WebCore::CaptureDevice&amp;);
+    static bool decode(Decoder&amp;, WebCore::CaptureDevice&amp;);
+};
+#endif
+
</ins><span class="cx"> } // namespace IPC
</span><span class="cx"> 
</span><span class="cx"> namespace WTF {
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessAPIAPIUIClienth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/API/APIUIClient.h (207462 => 207463)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/API/APIUIClient.h        2016-10-18 13:15:40 UTC (rev 207462)
+++ trunk/Source/WebKit2/UIProcess/API/APIUIClient.h        2016-10-18 14:53:06 UTC (rev 207463)
</span><span class="lines">@@ -51,7 +51,6 @@
</span><span class="cx"> class NativeWebKeyboardEvent;
</span><span class="cx"> class NativeWebWheelEvent;
</span><span class="cx"> class NotificationPermissionRequest;
</span><del>-class UserMediaPermissionCheckProxy;
</del><span class="cx"> class UserMediaPermissionRequestProxy;
</span><span class="cx"> class WebColorPickerResultListenerProxy;
</span><span class="cx"> class WebFrameProxy;
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessAPICWKUserMediaPermissionRequestcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/API/C/WKUserMediaPermissionRequest.cpp (207462 => 207463)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/API/C/WKUserMediaPermissionRequest.cpp        2016-10-18 13:15:40 UTC (rev 207462)
+++ trunk/Source/WebKit2/UIProcess/API/C/WKUserMediaPermissionRequest.cpp        2016-10-18 14:53:06 UTC (rev 207463)
</span><span class="lines">@@ -1,5 +1,6 @@
</span><span class="cx"> /*
</span><span class="cx">  * Copyright (C) 2014 Igalia S.L
</span><ins>+ * Copyright (C) 2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  *  This library is free software; you can redistribute it and/or
</span><span class="cx">  *  modify it under the terms of the GNU Lesser General Public
</span><span class="lines">@@ -38,11 +39,42 @@
</span><span class="cx">     toImpl(userMediaPermissionRequestRef)-&gt;allow(toWTFString(audioDeviceUID), toWTFString(videoDeviceUID));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void WKUserMediaPermissionRequestDeny(WKUserMediaPermissionRequestRef userMediaPermissionRequestRef)
</del><ins>+static UserMediaPermissionRequestProxy::UserMediaAccessDenialReason toWK(UserMediaPermissionRequestDenialReason reason)
</ins><span class="cx"> {
</span><del>-    toImpl(userMediaPermissionRequestRef)-&gt;deny();
</del><ins>+    switch (reason) {
+    case kWKNoConstraints:
+        return UserMediaPermissionRequestProxy::UserMediaAccessDenialReason::NoConstraints;
+        break;
+    case kWKUserMediaDisabled:
+        return UserMediaPermissionRequestProxy::UserMediaAccessDenialReason::UserMediaDisabled;
+        break;
+    case kWKNoCaptureDevices:
+        return UserMediaPermissionRequestProxy::UserMediaAccessDenialReason::NoCaptureDevices;
+        break;
+    case kWKInvalidConstraint:
+        return UserMediaPermissionRequestProxy::UserMediaAccessDenialReason::InvalidConstraint;
+        break;
+    case kWKHardwareError:
+        return UserMediaPermissionRequestProxy::UserMediaAccessDenialReason::HardwareError;
+        break;
+    case kWKPermissionDenied:
+        return UserMediaPermissionRequestProxy::UserMediaAccessDenialReason::PermissionDenied;
+        break;
+    case kWKOtherFailure:
+        return UserMediaPermissionRequestProxy::UserMediaAccessDenialReason::OtherFailure;
+        break;
+    }
+
+    ASSERT_NOT_REACHED();
+    return UserMediaPermissionRequestProxy::UserMediaAccessDenialReason::OtherFailure;
+    
</ins><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void WKUserMediaPermissionRequestDeny(WKUserMediaPermissionRequestRef userMediaPermissionRequestRef, UserMediaPermissionRequestDenialReason reason)
+{
+    toImpl(userMediaPermissionRequestRef)-&gt;deny(toWK(reason));
+}
+
</ins><span class="cx"> WKArrayRef WKUserMediaPermissionRequestVideoDeviceUIDs(WKUserMediaPermissionRequestRef userMediaPermissionRef)
</span><span class="cx"> {
</span><span class="cx">     WKMutableArrayRef array = WKMutableArrayCreate();
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessAPICWKUserMediaPermissionRequesth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/API/C/WKUserMediaPermissionRequest.h (207462 => 207463)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/API/C/WKUserMediaPermissionRequest.h        2016-10-18 13:15:40 UTC (rev 207462)
+++ trunk/Source/WebKit2/UIProcess/API/C/WKUserMediaPermissionRequest.h        2016-10-18 14:53:06 UTC (rev 207463)
</span><span class="lines">@@ -1,5 +1,6 @@
</span><span class="cx"> /*
</span><span class="cx">  * Copyright (C) 2014 Igalia S.L
</span><ins>+ * Copyright (C) 2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  *  This library is free software; you can redistribute it and/or
</span><span class="cx">  *  modify it under the terms of the GNU Lesser General Public
</span><span class="lines">@@ -27,8 +28,19 @@
</span><span class="cx"> 
</span><span class="cx"> WK_EXPORT WKTypeID WKUserMediaPermissionRequestGetTypeID();
</span><span class="cx"> 
</span><ins>+enum {
+    kWKNoConstraints = 0,
+    kWKUserMediaDisabled,
+    kWKNoCaptureDevices,
+    kWKInvalidConstraint,
+    kWKHardwareError,
+    kWKPermissionDenied,
+    kWKOtherFailure
+};
+typedef uint32_t UserMediaPermissionRequestDenialReason;
+
</ins><span class="cx"> WK_EXPORT void WKUserMediaPermissionRequestAllow(WKUserMediaPermissionRequestRef, WKStringRef audioDeviceUID, WKStringRef videoDeviceUID);
</span><del>-WK_EXPORT void WKUserMediaPermissionRequestDeny(WKUserMediaPermissionRequestRef);
</del><ins>+WK_EXPORT void WKUserMediaPermissionRequestDeny(WKUserMediaPermissionRequestRef, UserMediaPermissionRequestDenialReason);
</ins><span class="cx"> 
</span><span class="cx"> WK_EXPORT WKArrayRef WKUserMediaPermissionRequestVideoDeviceUIDs(WKUserMediaPermissionRequestRef);
</span><span class="cx"> WK_EXPORT WKArrayRef WKUserMediaPermissionRequestAudioDeviceUIDs(WKUserMediaPermissionRequestRef);
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessAPIgtkWebKitUserMediaPermissionRequestcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/API/gtk/WebKitUserMediaPermissionRequest.cpp (207462 => 207463)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/API/gtk/WebKitUserMediaPermissionRequest.cpp        2016-10-18 13:15:40 UTC (rev 207462)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/WebKitUserMediaPermissionRequest.cpp        2016-10-18 14:53:06 UTC (rev 207463)
</span><span class="lines">@@ -91,7 +91,7 @@
</span><span class="cx">         return;
</span><span class="cx"> 
</span><span class="cx">     priv-&gt;madeDecision = true;
</span><del>-    priv-&gt;request-&gt;deny();
</del><ins>+    priv-&gt;request-&gt;deny(UserMediaPermissionRequestProxy::UserMediaAccessDenialReason::PermissionDenied);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> static void webkit_permission_request_interface_init(WebKitPermissionRequestIface* iface)
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessUserMediaPermissionRequestManagerProxycpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/UserMediaPermissionRequestManagerProxy.cpp (207462 => 207463)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/UserMediaPermissionRequestManagerProxy.cpp        2016-10-18 13:15:40 UTC (rev 207462)
+++ trunk/Source/WebKit2/UIProcess/UserMediaPermissionRequestManagerProxy.cpp        2016-10-18 14:53:06 UTC (rev 207463)
</span><span class="lines">@@ -1,5 +1,6 @@
</span><span class="cx"> /*
</span><span class="cx">  * Copyright (C) 2014 Igalia S.L.
</span><ins>+ * Copyright (C) 2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  *  This library is free software; you can redistribute it and/or
</span><span class="cx">  *  modify it under the terms of the GNU Lesser General Public
</span><span class="lines">@@ -19,10 +20,17 @@
</span><span class="cx"> #include &quot;config.h&quot;
</span><span class="cx"> #include &quot;UserMediaPermissionRequestManagerProxy.h&quot;
</span><span class="cx"> 
</span><ins>+#include &quot;APISecurityOrigin.h&quot;
+#include &quot;APIUIClient.h&quot;
</ins><span class="cx"> #include &quot;WebPageMessages.h&quot;
</span><span class="cx"> #include &quot;WebPageProxy.h&quot;
</span><span class="cx"> #include &quot;WebProcessProxy.h&quot;
</span><ins>+#include &lt;WebCore/MediaConstraintsImpl.h&gt;
+#include &lt;WebCore/MockRealtimeMediaSourceCenter.h&gt;
+#include &lt;WebCore/RealtimeMediaSource.h&gt;
</ins><span class="cx"> 
</span><ins>+using namespace WebCore;
+
</ins><span class="cx"> namespace WebKit {
</span><span class="cx"> 
</span><span class="cx"> UserMediaPermissionRequestManagerProxy::UserMediaPermissionRequestManagerProxy(WebPageProxy&amp; page)
</span><span class="lines">@@ -34,8 +42,11 @@
</span><span class="cx"> {
</span><span class="cx">     for (auto&amp; request : m_pendingUserMediaRequests.values())
</span><span class="cx">         request-&gt;invalidate();
</span><ins>+    m_pendingUserMediaRequests.clear();
</ins><span class="cx"> 
</span><del>-    m_pendingUserMediaRequests.clear();
</del><ins>+    for (auto&amp; request : m_pendingDeviceRequests.values())
+        request-&gt;invalidate();
+    m_pendingDeviceRequests.clear();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> Ref&lt;UserMediaPermissionRequestProxy&gt; UserMediaPermissionRequestManagerProxy::createRequest(uint64_t userMediaID, const Vector&lt;String&gt;&amp; audioDeviceUIDs, const Vector&lt;String&gt;&amp; videoDeviceUIDs)
</span><span class="lines">@@ -45,8 +56,47 @@
</span><span class="cx">     return request;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void UserMediaPermissionRequestManagerProxy::didReceiveUserMediaPermissionDecision(uint64_t userMediaID, bool allowed, const String&amp; audioDeviceUID, const String&amp; videoDeviceUID)
</del><ins>+Ref&lt;UserMediaPermissionRequestProxy&gt; UserMediaPermissionRequestManagerProxy::createRequest(uint64_t userMediaID)
</ins><span class="cx"> {
</span><ins>+    Ref&lt;UserMediaPermissionRequestProxy&gt; request = UserMediaPermissionRequestProxy::create(*this, userMediaID, Vector&lt;String&gt;(), Vector&lt;String&gt;());
+    m_pendingUserMediaRequests.add(userMediaID, request.ptr());
+    return request;
+}
+
+#if ENABLE(MEDIA_STREAM)
+static uint64_t toWebCore(UserMediaPermissionRequestProxy::UserMediaAccessDenialReason reason)
+{
+    switch (reason) {
+    case UserMediaPermissionRequestProxy::UserMediaAccessDenialReason::NoConstraints:
+        return static_cast&lt;uint64_t&gt;(UserMediaRequest::MediaAccessDenialReason::NoConstraints);
+        break;
+    case UserMediaPermissionRequestProxy::UserMediaAccessDenialReason::UserMediaDisabled:
+        return static_cast&lt;uint64_t&gt;(UserMediaRequest::MediaAccessDenialReason::UserMediaDisabled);
+        break;
+    case UserMediaPermissionRequestProxy::UserMediaAccessDenialReason::NoCaptureDevices:
+        return static_cast&lt;uint64_t&gt;(UserMediaRequest::MediaAccessDenialReason::NoCaptureDevices);
+        break;
+    case UserMediaPermissionRequestProxy::UserMediaAccessDenialReason::InvalidConstraint:
+        return static_cast&lt;uint64_t&gt;(UserMediaRequest::MediaAccessDenialReason::InvalidConstraint);
+        break;
+    case UserMediaPermissionRequestProxy::UserMediaAccessDenialReason::HardwareError:
+        return static_cast&lt;uint64_t&gt;(UserMediaRequest::MediaAccessDenialReason::HardwareError);
+        break;
+    case UserMediaPermissionRequestProxy::UserMediaAccessDenialReason::PermissionDenied:
+        return static_cast&lt;uint64_t&gt;(UserMediaRequest::MediaAccessDenialReason::PermissionDenied);
+        break;
+    case UserMediaPermissionRequestProxy::UserMediaAccessDenialReason::OtherFailure:
+        return static_cast&lt;uint64_t&gt;(UserMediaRequest::MediaAccessDenialReason::OtherFailure);
+        break;
+    }
+    
+    ASSERT_NOT_REACHED();
+    return static_cast&lt;uint64_t&gt;(UserMediaRequest::MediaAccessDenialReason::OtherFailure);
+}
+#endif
+
+void UserMediaPermissionRequestManagerProxy::userMediaAccessWasDenied(uint64_t userMediaID, UserMediaPermissionRequestProxy::UserMediaAccessDenialReason reason)
+{
</ins><span class="cx">     if (!m_page.isValid())
</span><span class="cx">         return;
</span><span class="cx"> 
</span><span class="lines">@@ -53,21 +103,110 @@
</span><span class="cx">     if (!m_pendingUserMediaRequests.take(userMediaID))
</span><span class="cx">         return;
</span><span class="cx"> 
</span><ins>+    denyRequest(userMediaID, reason, &quot;&quot;);
+}
+
+void UserMediaPermissionRequestManagerProxy::denyRequest(uint64_t userMediaID, UserMediaPermissionRequestProxy::UserMediaAccessDenialReason reason, const String&amp; invalidConstraint)
+{
+    ASSERT(m_page.isValid());
+
</ins><span class="cx"> #if ENABLE(MEDIA_STREAM)
</span><del>-    m_page.process().send(Messages::WebPage::DidReceiveUserMediaPermissionDecision(userMediaID, allowed, audioDeviceUID, videoDeviceUID), m_page.pageID());
</del><ins>+    m_page.process().send(Messages::WebPage::UserMediaAccessWasDenied(userMediaID, toWebCore(reason), invalidConstraint), m_page.pageID());
</ins><span class="cx"> #else
</span><del>-    UNUSED_PARAM(allowed);
</del><ins>+    UNUSED_PARAM(reason);
+    UNUSED_PARAM(invalidConstraint);
</ins><span class="cx"> #endif
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-Ref&lt;UserMediaPermissionCheckProxy&gt; UserMediaPermissionRequestManagerProxy::createUserMediaPermissionCheck(uint64_t userMediaID)
</del><ins>+void UserMediaPermissionRequestManagerProxy::userMediaAccessWasGranted(uint64_t userMediaID, const String&amp; audioDeviceUID, const String&amp; videoDeviceUID)
</ins><span class="cx"> {
</span><del>-    Ref&lt;UserMediaPermissionCheckProxy&gt; request = UserMediaPermissionCheckProxy::create(*this, userMediaID);
</del><ins>+    if (!m_page.isValid())
+        return;
+
+    if (!m_pendingUserMediaRequests.take(userMediaID))
+        return;
+
+#if ENABLE(MEDIA_STREAM)
+    m_page.process().send(Messages::WebPage::UserMediaAccessWasGranted(userMediaID, audioDeviceUID, videoDeviceUID), m_page.pageID());
+#else
+    UNUSED_PARAM(audioDeviceUID);
+    UNUSED_PARAM(videoDeviceUID);
+#endif
+}
+
+void UserMediaPermissionRequestManagerProxy::requestUserMediaPermissionForFrame(uint64_t userMediaID, uint64_t frameID, String userMediaDocumentOriginIdentifier, String topLevelDocumentOriginIdentifier, const WebCore::MediaConstraintsData&amp; audioConstraintsData, const WebCore::MediaConstraintsData&amp; videoConstraintsData)
+{
+#if ENABLE(MEDIA_STREAM)
+    RealtimeMediaSourceCenter::InvalidConstraintsHandler invalidHandler = [this, userMediaID, frameID, userMediaDocumentOriginIdentifier, topLevelDocumentOriginIdentifier](const String&amp; invalidConstraint) {
+        if (!m_page.isValid())
+            return;
+
+        denyRequest(userMediaID, UserMediaPermissionRequestProxy::UserMediaAccessDenialReason::InvalidConstraint, invalidConstraint);
+    };
+
+    RealtimeMediaSourceCenter::ValidConstraintsHandler validHandler = [this, userMediaID, frameID, userMediaDocumentOriginIdentifier, topLevelDocumentOriginIdentifier](const Vector&lt;RefPtr&lt;RealtimeMediaSource&gt;&gt;&amp;&amp; audioTracks, const Vector&lt;RefPtr&lt;RealtimeMediaSource&gt;&gt;&amp;&amp; videoTracks) {
+        if (!m_page.isValid())
+            return;
+
+        Vector&lt;String&gt; videoDeviceUIDs;
+        Vector&lt;String&gt; audioDeviceUIDs;
+        for (auto&amp; audioTrack : audioTracks)
+            audioDeviceUIDs.append(audioTrack-&gt;persistentID());
+        for (auto&amp; videoTrack : videoTracks)
+            videoDeviceUIDs.append(videoTrack-&gt;persistentID());
+
+        if (videoDeviceUIDs.isEmpty() &amp;&amp; audioDeviceUIDs.isEmpty()) {
+            denyRequest(userMediaID, UserMediaPermissionRequestProxy::UserMediaAccessDenialReason::NoConstraints, &quot;&quot;);
+            return;
+        }
+
+        auto userMediaOrigin = API::SecurityOrigin::create(SecurityOrigin::createFromDatabaseIdentifier(userMediaDocumentOriginIdentifier));
+        auto topLevelOrigin = API::SecurityOrigin::create(SecurityOrigin::createFromDatabaseIdentifier(topLevelDocumentOriginIdentifier));
+        auto request = createRequest(userMediaID, audioDeviceUIDs, videoDeviceUIDs);
+
+        if (!m_page.uiClient().decidePolicyForUserMediaPermissionRequest(m_page, *m_page.process().webFrame(frameID), *userMediaOrigin.get(), *topLevelOrigin.get(), request.get())) {
+            m_pendingUserMediaRequests.take(userMediaID);
+            request-&gt;deny(UserMediaPermissionRequestProxy::UserMediaAccessDenialReason::UserMediaDisabled);
+        }
+    };
+
+    auto audioConstraints = MediaConstraintsImpl::create(audioConstraintsData);
+    auto videoConstraints = MediaConstraintsImpl::create(videoConstraintsData);
+
+    syncWithWebCorePrefs();
+    RealtimeMediaSourceCenter::singleton().validateRequestConstraints(validHandler, invalidHandler, audioConstraints, videoConstraints);
+#else
+    UNUSED_PARAM(userMediaID);
+    UNUSED_PARAM(frameID);
+    UNUSED_PARAM(userMediaDocumentOriginIdentifier);
+    UNUSED_PARAM(topLevelDocumentOriginIdentifier);
+    UNUSED_PARAM(audioConstraintsData);
+    UNUSED_PARAM(videoConstraintsData);
+#endif
+}
+
+void UserMediaPermissionRequestManagerProxy::enumerateMediaDevicesForFrame(uint64_t userMediaID, uint64_t frameID, String userMediaDocumentOriginIdentifier, String topLevelDocumentOriginIdentifier)
+{
+#if ENABLE(MEDIA_STREAM)
+    auto request = UserMediaPermissionCheckProxy::create(*this, userMediaID);
</ins><span class="cx">     m_pendingDeviceRequests.add(userMediaID, request.ptr());
</span><del>-    return request;
</del><ins>+
+    auto userMediaOrigin = API::SecurityOrigin::create(SecurityOrigin::createFromDatabaseIdentifier(userMediaDocumentOriginIdentifier));
+    auto topLevelOrigin = API::SecurityOrigin::create(SecurityOrigin::createFromDatabaseIdentifier(topLevelDocumentOriginIdentifier));
+
+    if (!m_page.uiClient().checkUserMediaPermissionForOrigin(m_page, *m_page.process().webFrame(frameID), *userMediaOrigin.get(), *topLevelOrigin.get(), request.get())) {
+        m_pendingDeviceRequests.take(userMediaID);
+        m_page.process().send(Messages::WebPage::DidCompleteMediaDeviceEnumeration(userMediaID, Vector&lt;WebCore::CaptureDevice&gt;(), emptyString(), false), m_page.pageID());
+    }
+#else
+    UNUSED_PARAM(userMediaID);
+    UNUSED_PARAM(frameID);
+    UNUSED_PARAM(userMediaDocumentOriginIdentifier);
+    UNUSED_PARAM(topLevelDocumentOriginIdentifier);
+#endif
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-void UserMediaPermissionRequestManagerProxy::didCompleteUserMediaPermissionCheck(uint64_t userMediaID, const String&amp; mediaDeviceIdentifierHashSalt, bool allowed)
</del><ins>+void UserMediaPermissionRequestManagerProxy::didCompleteUserMediaPermissionCheck(uint64_t userMediaID, const String&amp; deviceIdentifierHashSalt, bool originHasPersistentAccess)
</ins><span class="cx"> {
</span><span class="cx">     if (!m_page.isValid())
</span><span class="cx">         return;
</span><span class="lines">@@ -76,10 +215,23 @@
</span><span class="cx">         return;
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(MEDIA_STREAM)
</span><del>-    m_page.process().send(Messages::WebPage::DidCompleteUserMediaPermissionCheck(userMediaID, mediaDeviceIdentifierHashSalt, allowed), m_page.pageID());
</del><ins>+    syncWithWebCorePrefs();
+    auto deviceInfo = RealtimeMediaSourceCenter::singleton().getMediaStreamDevices();
+    m_page.process().send(Messages::WebPage::DidCompleteMediaDeviceEnumeration(userMediaID, deviceInfo, deviceIdentifierHashSalt, originHasPersistentAccess), m_page.pageID());
</ins><span class="cx"> #else
</span><del>-    UNUSED_PARAM(allowed);
</del><ins>+    UNUSED_PARAM(deviceIdentifierHashSalt);
+    UNUSED_PARAM(originHasPersistentAccess);
</ins><span class="cx"> #endif
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void UserMediaPermissionRequestManagerProxy::syncWithWebCorePrefs() const
+{
+#if ENABLE(MEDIA_STREAM)
+    // Enable/disable the mock capture devices for the UI process as per the WebCore preferences. Note that
+    // this is a noop if the preference hasn't changed since the last time this was called.
+    bool mockDevicesEnabled = m_page.preferences().mockCaptureDevicesEnabled();
+    WebCore::MockRealtimeMediaSourceCenter::setMockRealtimeMediaSourceCenterEnabled(mockDevicesEnabled);
+#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 (207462 => 207463)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/UserMediaPermissionRequestManagerProxy.h        2016-10-18 13:15:40 UTC (rev 207462)
+++ trunk/Source/WebKit2/UIProcess/UserMediaPermissionRequestManagerProxy.h        2016-10-18 14:53:06 UTC (rev 207463)
</span><span class="lines">@@ -1,5 +1,6 @@
</span><span class="cx"> /*
</span><span class="cx">  * Copyright (C) 2014 Igalia S.L.
</span><ins>+ * Copyright (C) 2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  *  This library is free software; you can redistribute it and/or
</span><span class="cx">  *  modify it under the terms of the GNU Lesser General Public
</span><span class="lines">@@ -21,8 +22,14 @@
</span><span class="cx"> 
</span><span class="cx"> #include &quot;UserMediaPermissionCheckProxy.h&quot;
</span><span class="cx"> #include &quot;UserMediaPermissionRequestProxy.h&quot;
</span><ins>+#include &lt;WebCore/UserMediaRequest.h&gt;
</ins><span class="cx"> #include &lt;wtf/HashMap.h&gt;
</span><span class="cx"> 
</span><ins>+namespace WebCore {
+class CaptureDevice;
+struct MediaConstraintsData;
+};
+
</ins><span class="cx"> namespace WebKit {
</span><span class="cx"> 
</span><span class="cx"> class WebPageProxy;
</span><span class="lines">@@ -33,16 +40,25 @@
</span><span class="cx"> 
</span><span class="cx">     void invalidateRequests();
</span><span class="cx"> 
</span><del>-    Ref&lt;UserMediaPermissionRequestProxy&gt; createRequest(uint64_t userMediaID, const Vector&lt;String&gt;&amp; audioDeviceUIDs, const Vector&lt;String&gt;&amp; videoDeviceUIDs);
-    void didReceiveUserMediaPermissionDecision(uint64_t, bool allow, const String&amp; audioDeviceUID, const String&amp; videoDeviceUID);
</del><ins>+    void requestUserMediaPermissionForFrame(uint64_t userMediaID, uint64_t frameID, String userMediaDocumentOriginIdentifier, String topLevelDocumentOriginIdentifier, const WebCore::MediaConstraintsData&amp; audioConstraintsData, const WebCore::MediaConstraintsData&amp; videoConstraintsData);
</ins><span class="cx"> 
</span><ins>+    void userMediaAccessWasGranted(uint64_t, const String&amp; audioDeviceUID, const String&amp; videoDeviceUID);
+    void userMediaAccessWasDenied(uint64_t, UserMediaPermissionRequestProxy::UserMediaAccessDenialReason);
</ins><span class="cx"> 
</span><del>-    Ref&lt;UserMediaPermissionCheckProxy&gt; createUserMediaPermissionCheck(uint64_t userMediaID);
</del><ins>+    void enumerateMediaDevicesForFrame(uint64_t userMediaID, uint64_t frameID, String userMediaDocumentOriginIdentifier, String topLevelDocumentOriginIdentifier);
+
</ins><span class="cx">     void didCompleteUserMediaPermissionCheck(uint64_t, const String&amp;, bool allow);
</span><span class="cx"> 
</span><span class="cx"> private:
</span><ins>+    Ref&lt;UserMediaPermissionRequestProxy&gt; createRequest(uint64_t, const Vector&lt;String&gt;&amp; audioDeviceUIDs, const Vector&lt;String&gt;&amp; videoDeviceUIDs);
+    Ref&lt;UserMediaPermissionRequestProxy&gt; createRequest(uint64_t userMediaID);
+    void denyRequest(uint64_t userMediaID, UserMediaPermissionRequestProxy::UserMediaAccessDenialReason, const String&amp; invalidConstraint);
+    Ref&lt;UserMediaPermissionCheckProxy&gt; createUserMediaPermissionCheck(uint64_t userMediaID);
+    void syncWithWebCorePrefs() const;
+
</ins><span class="cx">     HashMap&lt;uint64_t, RefPtr&lt;UserMediaPermissionRequestProxy&gt;&gt; m_pendingUserMediaRequests;
</span><span class="cx">     HashMap&lt;uint64_t, RefPtr&lt;UserMediaPermissionCheckProxy&gt;&gt; m_pendingDeviceRequests;
</span><ins>+
</ins><span class="cx">     WebPageProxy&amp; m_page;
</span><span class="cx"> };
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessUserMediaPermissionRequestProxycpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/UserMediaPermissionRequestProxy.cpp (207462 => 207463)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/UserMediaPermissionRequestProxy.cpp        2016-10-18 13:15:40 UTC (rev 207462)
+++ trunk/Source/WebKit2/UIProcess/UserMediaPermissionRequestProxy.cpp        2016-10-18 14:53:06 UTC (rev 207463)
</span><span class="lines">@@ -1,5 +1,6 @@
</span><span class="cx"> /*
</span><span class="cx">  * Copyright (C) 2014 Igalia S.L.
</span><ins>+ * Copyright (C) 2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  *  This library is free software; you can redistribute it and/or
</span><span class="cx">  *  modify it under the terms of the GNU Lesser General Public
</span><span class="lines">@@ -39,18 +40,18 @@
</span><span class="cx">     if (!m_manager)
</span><span class="cx">         return;
</span><span class="cx"> 
</span><del>-    m_manager-&gt;didReceiveUserMediaPermissionDecision(m_userMediaID, true, audioDeviceUID, videoDeviceUID);
-    m_manager = nullptr;
</del><ins>+    m_manager-&gt;userMediaAccessWasGranted(m_userMediaID, audioDeviceUID, videoDeviceUID);
+    invalidate();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-void UserMediaPermissionRequestProxy::deny()
</del><ins>+void UserMediaPermissionRequestProxy::deny(UserMediaAccessDenialReason reason)
</ins><span class="cx"> {
</span><span class="cx">     ASSERT(m_manager);
</span><span class="cx">     if (!m_manager)
</span><span class="cx">         return;
</span><span class="cx"> 
</span><del>-    m_manager-&gt;didReceiveUserMediaPermissionDecision(m_userMediaID, false, emptyString(), emptyString());
-    m_manager = nullptr;
</del><ins>+    m_manager-&gt;userMediaAccessWasDenied(m_userMediaID, reason);
+    invalidate();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void UserMediaPermissionRequestProxy::invalidate()
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessUserMediaPermissionRequestProxyh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/UserMediaPermissionRequestProxy.h (207462 => 207463)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/UserMediaPermissionRequestProxy.h        2016-10-18 13:15:40 UTC (rev 207462)
+++ trunk/Source/WebKit2/UIProcess/UserMediaPermissionRequestProxy.h        2016-10-18 14:53:06 UTC (rev 207463)
</span><span class="lines">@@ -1,5 +1,6 @@
</span><span class="cx"> /*
</span><span class="cx">  * Copyright (C) 2014 Igalia S.L.
</span><ins>+ * Copyright (C) 2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  *  This library is free software; you can redistribute it and/or
</span><span class="cx">  *  modify it under the terms of the GNU Lesser General Public
</span><span class="lines">@@ -20,7 +21,7 @@
</span><span class="cx"> #define UserMediaPermissionRequestProxy_h
</span><span class="cx"> 
</span><span class="cx"> #include &quot;APIObject.h&quot;
</span><del>-#include &lt;WebCore/RealtimeMediaSource.h&gt;
</del><ins>+#include &lt;WebCore/UserMediaRequest.h&gt;
</ins><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">@@ -36,8 +37,10 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     void allow(const String&amp; videoDeviceUID, const String&amp; audioDeviceUID);
</span><del>-    void deny();
</del><span class="cx"> 
</span><ins>+    enum class UserMediaAccessDenialReason { NoConstraints, UserMediaDisabled, NoCaptureDevices, InvalidConstraint, HardwareError, PermissionDenied, OtherFailure };
+    void deny(UserMediaAccessDenialReason);
+
</ins><span class="cx">     void invalidate();
</span><span class="cx"> 
</span><span class="cx">     bool requiresAudio() const { return m_audioDeviceUIDs.size(); }
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessWebPageProxycpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp (207462 => 207463)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp        2016-10-18 13:15:40 UTC (rev 207462)
+++ trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp        2016-10-18 14:53:06 UTC (rev 207463)
</span><span class="lines">@@ -178,6 +178,10 @@
</span><span class="cx"> #include &quot;WebPlaybackSessionManagerProxy.h&quot;
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+#if ENABLE(MEDIA_STREAM)
+#include &lt;WebCore/MediaConstraintsImpl.h&gt;
+#endif
+
</ins><span class="cx"> // This controls what strategy we use for mouse wheel coalescing.
</span><span class="cx"> #define MERGE_WHEEL_EVENTS 1
</span><span class="cx"> 
</span><span class="lines">@@ -5630,39 +5634,29 @@
</span><span class="cx">     request-&gt;deny();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void WebPageProxy::requestUserMediaPermissionForFrame(uint64_t userMediaID, uint64_t frameID, String userMediaDocumentOriginIdentifier, String topLevelDocumentOriginIdentifier, const Vector&lt;String&gt;&amp; audioDeviceUIDs, const Vector&lt;String&gt;&amp; videoDeviceUIDs)
</del><ins>+void WebPageProxy::requestUserMediaPermissionForFrame(uint64_t userMediaID, uint64_t frameID, String userMediaDocumentOriginIdentifier, String topLevelDocumentOriginIdentifier, const WebCore::MediaConstraintsData&amp; audioConstraintsData, const WebCore::MediaConstraintsData&amp; videoConstraintsData)
</ins><span class="cx"> {
</span><span class="cx"> #if ENABLE(MEDIA_STREAM)
</span><del>-    WebFrameProxy* frame = m_process-&gt;webFrame(frameID);
-    MESSAGE_CHECK(frame);
</del><ins>+    MESSAGE_CHECK(m_process-&gt;webFrame(frameID));
</ins><span class="cx"> 
</span><del>-    RefPtr&lt;API::SecurityOrigin&gt; userMediaOrigin = API::SecurityOrigin::create(SecurityOrigin::createFromDatabaseIdentifier(userMediaDocumentOriginIdentifier));
-    RefPtr&lt;API::SecurityOrigin&gt; topLevelOrigin = API::SecurityOrigin::create(SecurityOrigin::createFromDatabaseIdentifier(topLevelDocumentOriginIdentifier));
-    RefPtr&lt;UserMediaPermissionRequestProxy&gt; request = m_userMediaPermissionRequestManager.createRequest(userMediaID, audioDeviceUIDs, videoDeviceUIDs);
-
-    if (!m_uiClient-&gt;decidePolicyForUserMediaPermissionRequest(*this, *frame, *userMediaOrigin.get(), *topLevelOrigin.get(), *request.get()))
-        request-&gt;deny();
</del><ins>+    m_userMediaPermissionRequestManager.requestUserMediaPermissionForFrame(userMediaID, frameID, userMediaDocumentOriginIdentifier, topLevelDocumentOriginIdentifier, audioConstraintsData, videoConstraintsData);
</ins><span class="cx"> #else
</span><span class="cx">     UNUSED_PARAM(userMediaID);
</span><span class="cx">     UNUSED_PARAM(frameID);
</span><span class="cx">     UNUSED_PARAM(userMediaDocumentOriginIdentifier);
</span><span class="cx">     UNUSED_PARAM(topLevelDocumentOriginIdentifier);
</span><del>-    UNUSED_PARAM(audioDeviceUIDs);
-    UNUSED_PARAM(videoDeviceUIDs);
</del><ins>+    UNUSED_PARAM(audioConstraintsData);
+    UNUSED_PARAM(videoConstraintsData);
</ins><span class="cx"> #endif
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void WebPageProxy::checkUserMediaPermissionForFrame(uint64_t userMediaID, uint64_t frameID, String userMediaDocumentOriginIdentifier, String topLevelDocumentOriginIdentifier)
</del><ins>+void WebPageProxy::enumerateMediaDevicesForFrame(uint64_t userMediaID, uint64_t frameID, String userMediaDocumentOriginIdentifier, String topLevelDocumentOriginIdentifier)
</ins><span class="cx"> {
</span><span class="cx"> #if ENABLE(MEDIA_STREAM)
</span><span class="cx">     WebFrameProxy* frame = m_process-&gt;webFrame(frameID);
</span><span class="cx">     MESSAGE_CHECK(frame);
</span><span class="cx"> 
</span><del>-    RefPtr&lt;UserMediaPermissionCheckProxy&gt; request = m_userMediaPermissionRequestManager.createUserMediaPermissionCheck(userMediaID);
-    RefPtr&lt;API::SecurityOrigin&gt; userMediaOrigin = API::SecurityOrigin::create(SecurityOrigin::createFromDatabaseIdentifier(userMediaDocumentOriginIdentifier));
-    RefPtr&lt;API::SecurityOrigin&gt; topLevelOrigin = API::SecurityOrigin::create(SecurityOrigin::createFromDatabaseIdentifier(topLevelDocumentOriginIdentifier));
-    if (!m_uiClient-&gt;checkUserMediaPermissionForOrigin(*this, *frame, *userMediaOrigin.get(), *topLevelOrigin.get(), *request.get()))
-        request-&gt;setUserMediaAccessInfo(emptyString(), false);
</del><ins>+    m_userMediaPermissionRequestManager.enumerateMediaDevicesForFrame(userMediaID, frameID, userMediaDocumentOriginIdentifier, topLevelDocumentOriginIdentifier);
</ins><span class="cx"> #else
</span><span class="cx">     UNUSED_PARAM(userMediaID);
</span><span class="cx">     UNUSED_PARAM(frameID);
</span><span class="lines">@@ -5671,6 +5665,7 @@
</span><span class="cx"> #endif
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+
</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 (207462 => 207463)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/WebPageProxy.h        2016-10-18 13:15:40 UTC (rev 207462)
+++ trunk/Source/WebKit2/UIProcess/WebPageProxy.h        2016-10-18 14:53:06 UTC (rev 207463)
</span><span class="lines">@@ -156,6 +156,7 @@
</span><span class="cx"> struct DictionaryPopupInfo;
</span><span class="cx"> struct ExceptionDetails;
</span><span class="cx"> struct FileChooserSettings;
</span><ins>+struct MediaConstraintsData;
</ins><span class="cx"> struct SecurityOriginData;
</span><span class="cx"> struct TextAlternativeWithRange;
</span><span class="cx"> struct TextCheckingResult;
</span><span class="lines">@@ -1249,8 +1250,8 @@
</span><span class="cx">     void reachedApplicationCacheOriginQuota(const String&amp; originIdentifier, uint64_t currentQuota, uint64_t totalBytesNeeded, PassRefPtr&lt;Messages::WebPageProxy::ReachedApplicationCacheOriginQuota::DelayedReply&gt;);
</span><span class="cx">     void requestGeolocationPermissionForFrame(uint64_t geolocationID, uint64_t frameID, String originIdentifier);
</span><span class="cx"> 
</span><del>-    void requestUserMediaPermissionForFrame(uint64_t userMediaID, uint64_t frameID, String userMediaDocumentOriginIdentifier, String topLevelDocumentOriginIdentifier, const Vector&lt;String&gt;&amp; audioDeviceUIDs, const Vector&lt;String&gt;&amp; videoDeviceUIDs);
-    void checkUserMediaPermissionForFrame(uint64_t userMediaID, uint64_t frameID, String userMediaDocumentOriginIdentifier, String topLevelDocumentOriginIdentifier);
</del><ins>+    void requestUserMediaPermissionForFrame(uint64_t userMediaID, uint64_t frameID, String userMediaDocumentOriginIdentifier, String topLevelDocumentOriginIdentifier, const WebCore::MediaConstraintsData&amp; audioConstraints, const WebCore::MediaConstraintsData&amp; videoConstraints);
+    void enumerateMediaDevicesForFrame(uint64_t userMediaID, uint64_t frameID, String userMediaDocumentOriginIdentifier, String topLevelDocumentOriginIdentifier);
</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 (207462 => 207463)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/WebPageProxy.messages.in        2016-10-18 13:15:40 UTC (rev 207462)
+++ trunk/Source/WebKit2/UIProcess/WebPageProxy.messages.in        2016-10-18 14:53:06 UTC (rev 207463)
</span><span class="lines">@@ -271,8 +271,8 @@
</span><span class="cx">     
</span><span class="cx"> #if ENABLE(MEDIA_STREAM)
</span><span class="cx">     # MediaSteam messages
</span><del>-    RequestUserMediaPermissionForFrame(uint64_t userMediaID, uint64_t frameID, String userMediaDocumentOriginIdentifier, String topLevelDocumentOriginIdentifier, Vector&lt;String&gt; audioDeviceUIDs, Vector&lt;String&gt; videoDeviceUIDs)
-    CheckUserMediaPermissionForFrame(uint64_t userMediaID, uint64_t frameID, String userMediaDocumentOriginIdentifier, String topLevelDocumentOriginIdentifier)
</del><ins>+    RequestUserMediaPermissionForFrame(uint64_t userMediaID, uint64_t frameID, String userMediaDocumentOriginIdentifier, String topLevelDocumentOriginIdentifier, struct WebCore::MediaConstraintsData audioConstraintsData, struct WebCore::MediaConstraintsData videoConstraintsData)
+    EnumerateMediaDevicesForFrame(uint64_t userMediaID, uint64_t frameID, String userMediaDocumentOriginIdentifier, String topLevelDocumentOriginIdentifier)
</ins><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx">     # Notification messages
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessMediaStreamUserMediaPermissionRequestManagercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/MediaStream/UserMediaPermissionRequestManager.cpp (207462 => 207463)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/MediaStream/UserMediaPermissionRequestManager.cpp        2016-10-18 13:15:40 UTC (rev 207462)
+++ trunk/Source/WebKit2/WebProcess/MediaStream/UserMediaPermissionRequestManager.cpp        2016-10-18 14:53:06 UTC (rev 207463)
</span><span class="lines">@@ -1,5 +1,6 @@
</span><span class="cx"> /*
</span><span class="cx">  * Copyright (C) 2014 Igalia S.L.
</span><ins>+ * Copyright (C) 2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  *  This library is free software; you can redistribute it and/or
</span><span class="cx">  *  modify it under the terms of the GNU Lesser General Public
</span><span class="lines">@@ -21,10 +22,10 @@
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(MEDIA_STREAM)
</span><span class="cx"> 
</span><del>-#include &quot;WebCoreArgumentCoders.h&quot;
</del><span class="cx"> #include &quot;WebFrame.h&quot;
</span><span class="cx"> #include &quot;WebPage.h&quot;
</span><span class="cx"> #include &quot;WebPageProxyMessages.h&quot;
</span><ins>+#include &lt;WebCore/CaptureDevice.h&gt;
</ins><span class="cx"> #include &lt;WebCore/Document.h&gt;
</span><span class="cx"> #include &lt;WebCore/Frame.h&gt;
</span><span class="cx"> #include &lt;WebCore/FrameLoader.h&gt;
</span><span class="lines">@@ -34,6 +35,8 @@
</span><span class="cx"> 
</span><span class="cx"> namespace WebKit {
</span><span class="cx"> 
</span><ins>+using namespace WebCore;
+
</ins><span class="cx"> static uint64_t generateRequestID()
</span><span class="cx"> {
</span><span class="cx">     static uint64_t uniqueRequestID = 1;
</span><span class="lines">@@ -45,13 +48,17 @@
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+UserMediaPermissionRequestManager::~UserMediaPermissionRequestManager()
+{
+}
+
</ins><span class="cx"> void UserMediaPermissionRequestManager::startUserMediaRequest(UserMediaRequest&amp; request)
</span><span class="cx"> {
</span><del>-    Document* document = downcast&lt;Document&gt;(request.scriptExecutionContext());
</del><ins>+    Document* document = request.document();
</ins><span class="cx">     Frame* frame = document ? document-&gt;frame() : nullptr;
</span><span class="cx"> 
</span><span class="cx">     if (!frame) {
</span><del>-        request.userMediaAccessDenied();
</del><ins>+        request.deny(UserMediaRequest::OtherFailure, emptyString());
</ins><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -64,7 +71,7 @@
</span><span class="cx"> 
</span><span class="cx">     SecurityOrigin* topLevelDocumentOrigin = request.topLevelDocumentOrigin();
</span><span class="cx">     String topLevelDocumentOriginString = topLevelDocumentOrigin ? topLevelDocumentOrigin-&gt;databaseIdentifier() : emptyString();
</span><del>-    m_page.send(Messages::WebPageProxy::RequestUserMediaPermissionForFrame(requestID, webFrame-&gt;frameID(), request.userMediaDocumentOrigin()-&gt;databaseIdentifier(), topLevelDocumentOriginString, request.audioDeviceUIDs(), request.videoDeviceUIDs()));
</del><ins>+    m_page.send(Messages::WebPageProxy::RequestUserMediaPermissionForFrame(requestID, webFrame-&gt;frameID(), request.userMediaDocumentOrigin()-&gt;databaseIdentifier(), topLevelDocumentOriginString, request.audioConstraints().data(), request.videoConstraints().data()));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void UserMediaPermissionRequestManager::cancelUserMediaRequest(UserMediaRequest&amp; request)
</span><span class="lines">@@ -75,32 +82,39 @@
</span><span class="cx">     m_idToUserMediaRequestMap.remove(requestID);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void UserMediaPermissionRequestManager::didReceiveUserMediaPermissionDecision(uint64_t requestID, bool allowed, const String&amp; audioDeviceUID, const String&amp; videoDeviceUID)
</del><ins>+void UserMediaPermissionRequestManager::userMediaAccessWasGranted(uint64_t requestID, const String&amp; audioDeviceUID, const String&amp; videoDeviceUID)
</ins><span class="cx"> {
</span><del>-    RefPtr&lt;UserMediaRequest&gt; request = m_idToUserMediaRequestMap.take(requestID);
</del><ins>+    auto request = m_idToUserMediaRequestMap.take(requestID);
</ins><span class="cx">     if (!request)
</span><span class="cx">         return;
</span><span class="cx">     m_userMediaRequestToIDMap.remove(request);
</span><span class="cx"> 
</span><del>-    if (allowed)
-        request-&gt;userMediaAccessGranted(audioDeviceUID, videoDeviceUID);
-    else
-        request-&gt;userMediaAccessDenied();
</del><ins>+    request-&gt;allow(audioDeviceUID, videoDeviceUID);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-void UserMediaPermissionRequestManager::startUserMediaPermissionCheck(WebCore::UserMediaPermissionCheck&amp; request)
</del><ins>+void UserMediaPermissionRequestManager::userMediaAccessWasDenied(uint64_t requestID, WebCore::UserMediaRequest::MediaAccessDenialReason reason, const String&amp; invalidConstraint)
</ins><span class="cx"> {
</span><del>-    Document* document = downcast&lt;Document&gt;(request.scriptExecutionContext());
-    Frame* frame = document ? document-&gt;frame() : nullptr;
</del><ins>+    auto request = m_idToUserMediaRequestMap.take(requestID);
+    if (!request)
+        return;
+    m_userMediaRequestToIDMap.remove(request);
</ins><span class="cx"> 
</span><ins>+    request-&gt;deny(reason, invalidConstraint);
+}
+
+void UserMediaPermissionRequestManager::enumerateMediaDevices(MediaDevicesEnumerationRequest&amp; request)
+{
+    auto* document = downcast&lt;Document&gt;(request.scriptExecutionContext());
+    auto* frame = document ? document-&gt;frame() : nullptr;
+
</ins><span class="cx">     if (!frame) {
</span><del>-        request.setUserMediaAccessInfo(emptyString(), false);
</del><ins>+        request.setDeviceInfo(Vector&lt;CaptureDevice&gt;(), emptyString(), false);
</ins><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     uint64_t requestID = generateRequestID();
</span><del>-    m_idToUserMediaPermissionCheckMap.add(requestID, &amp;request);
-    m_userMediaPermissionCheckToIDMap.add(&amp;request, requestID);
</del><ins>+    m_idToMediaDevicesEnumerationRequestMap.add(requestID, &amp;request);
+    m_mediaDevicesEnumerationRequestToIDMap.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">@@ -107,25 +121,25 @@
</span><span class="cx"> 
</span><span class="cx">     SecurityOrigin* topLevelDocumentOrigin = request.topLevelDocumentOrigin();
</span><span class="cx">     String topLevelDocumentOriginString = topLevelDocumentOrigin ? topLevelDocumentOrigin-&gt;databaseIdentifier() : emptyString();
</span><del>-    m_page.send(Messages::WebPageProxy::CheckUserMediaPermissionForFrame(requestID, webFrame-&gt;frameID(), request.userMediaDocumentOrigin()-&gt;databaseIdentifier(), topLevelDocumentOriginString));
</del><ins>+    m_page.send(Messages::WebPageProxy::EnumerateMediaDevicesForFrame(requestID, webFrame-&gt;frameID(), request.userMediaDocumentOrigin()-&gt;databaseIdentifier(), topLevelDocumentOriginString));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-void UserMediaPermissionRequestManager::cancelUserMediaPermissionCheck(WebCore::UserMediaPermissionCheck&amp; request)
</del><ins>+void UserMediaPermissionRequestManager::cancelMediaDevicesEnumeration(WebCore::MediaDevicesEnumerationRequest&amp; request)
</ins><span class="cx"> {
</span><del>-    uint64_t requestID = m_userMediaPermissionCheckToIDMap.take(&amp;request);
</del><ins>+    uint64_t requestID = m_mediaDevicesEnumerationRequestToIDMap.take(&amp;request);
</ins><span class="cx">     if (!requestID)
</span><span class="cx">         return;
</span><del>-    m_idToUserMediaPermissionCheckMap.remove(requestID);
</del><ins>+    m_idToMediaDevicesEnumerationRequestMap.remove(requestID);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-void UserMediaPermissionRequestManager::didCompleteUserMediaPermissionCheck(uint64_t requestID, const String&amp; mediaDeviceIdentifierHashSalt, bool allowed)
</del><ins>+void UserMediaPermissionRequestManager::didCompleteMediaDeviceEnumeration(uint64_t requestID, const Vector&lt;CaptureDevice&gt;&amp; deviceList, const String&amp; mediaDeviceIdentifierHashSalt, bool hasPersistentAccess)
</ins><span class="cx"> {
</span><del>-    RefPtr&lt;UserMediaPermissionCheck&gt; request = m_idToUserMediaPermissionCheckMap.take(requestID);
</del><ins>+    RefPtr&lt;MediaDevicesEnumerationRequest&gt; request = m_idToMediaDevicesEnumerationRequestMap.take(requestID);
</ins><span class="cx">     if (!request)
</span><span class="cx">         return;
</span><del>-    m_userMediaPermissionCheckToIDMap.remove(request);
</del><ins>+    m_mediaDevicesEnumerationRequestToIDMap.remove(request);
</ins><span class="cx">     
</span><del>-    request-&gt;setUserMediaAccessInfo(mediaDeviceIdentifierHashSalt, allowed);
</del><ins>+    request-&gt;setDeviceInfo(deviceList, mediaDeviceIdentifierHashSalt, hasPersistentAccess);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> } // namespace WebKit
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessMediaStreamUserMediaPermissionRequestManagerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/MediaStream/UserMediaPermissionRequestManager.h (207462 => 207463)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/MediaStream/UserMediaPermissionRequestManager.h        2016-10-18 13:15:40 UTC (rev 207462)
+++ trunk/Source/WebKit2/WebProcess/MediaStream/UserMediaPermissionRequestManager.h        2016-10-18 14:53:06 UTC (rev 207463)
</span><span class="lines">@@ -1,5 +1,6 @@
</span><span class="cx"> /*
</span><span class="cx">  * Copyright (C) 2014 Igalia S.L.
</span><ins>+ * Copyright (C) 2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  *  This library is free software; you can redistribute it and/or
</span><span class="cx">  *  modify it under the terms of the GNU Lesser General Public
</span><span class="lines">@@ -21,7 +22,9 @@
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(MEDIA_STREAM)
</span><span class="cx"> 
</span><del>-#include &lt;WebCore/UserMediaPermissionCheck.h&gt;
</del><ins>+#include &lt;WebCore/MediaConstraints.h&gt;
+#include &lt;WebCore/MediaDevicesEnumerationRequest.h&gt;
+#include &lt;WebCore/UserMediaClient.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,14 +37,16 @@
</span><span class="cx"> class UserMediaPermissionRequestManager {
</span><span class="cx"> public:
</span><span class="cx">     explicit UserMediaPermissionRequestManager(WebPage&amp;);
</span><ins>+    ~UserMediaPermissionRequestManager();
</ins><span class="cx"> 
</span><span class="cx">     void startUserMediaRequest(WebCore::UserMediaRequest&amp;);
</span><span class="cx">     void cancelUserMediaRequest(WebCore::UserMediaRequest&amp;);
</span><del>-    void didReceiveUserMediaPermissionDecision(uint64_t requestID, bool allowed, const String&amp; audioDeviceUID, const String&amp; videoDeviceUID);
</del><ins>+    void userMediaAccessWasGranted(uint64_t, const String&amp; audioDeviceUID, const String&amp; videoDeviceUID);
+    void userMediaAccessWasDenied(uint64_t, WebCore::UserMediaRequest::MediaAccessDenialReason, const String&amp;);
</ins><span class="cx"> 
</span><del>-    void startUserMediaPermissionCheck(WebCore::UserMediaPermissionCheck&amp;);
-    void cancelUserMediaPermissionCheck(WebCore::UserMediaPermissionCheck&amp;);
-    void didCompleteUserMediaPermissionCheck(uint64_t requestID, const String&amp;, bool allowed);
</del><ins>+    void enumerateMediaDevices(WebCore::MediaDevicesEnumerationRequest&amp;);
+    void cancelMediaDevicesEnumeration(WebCore::MediaDevicesEnumerationRequest&amp;);
+    void didCompleteMediaDeviceEnumeration(uint64_t, const Vector&lt;WebCore::CaptureDevice&gt;&amp; deviceList, const String&amp; deviceIdentifierHashSalt, bool originHasPersistentAccess);
</ins><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     WebPage&amp; m_page;
</span><span class="lines">@@ -49,8 +54,8 @@
</span><span class="cx">     HashMap&lt;uint64_t, RefPtr&lt;WebCore::UserMediaRequest&gt;&gt; m_idToUserMediaRequestMap;
</span><span class="cx">     HashMap&lt;RefPtr&lt;WebCore::UserMediaRequest&gt;, uint64_t&gt; m_userMediaRequestToIDMap;
</span><span class="cx"> 
</span><del>-    HashMap&lt;uint64_t, RefPtr&lt;WebCore::UserMediaPermissionCheck&gt;&gt; m_idToUserMediaPermissionCheckMap;
-    HashMap&lt;RefPtr&lt;WebCore::UserMediaPermissionCheck&gt;, uint64_t&gt; m_userMediaPermissionCheckToIDMap;
</del><ins>+    HashMap&lt;uint64_t, RefPtr&lt;WebCore::MediaDevicesEnumerationRequest&gt;&gt; m_idToMediaDevicesEnumerationRequestMap;
+    HashMap&lt;RefPtr&lt;WebCore::MediaDevicesEnumerationRequest&gt;, uint64_t&gt; m_mediaDevicesEnumerationRequestToIDMap;
</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 (207462 => 207463)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebUserMediaClient.cpp        2016-10-18 13:15:40 UTC (rev 207462)
+++ trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebUserMediaClient.cpp        2016-10-18 14:53:06 UTC (rev 207463)
</span><span class="lines">@@ -1,5 +1,6 @@
</span><span class="cx"> /*
</span><span class="cx">  * Copyright (C) 2014 Igalia S.L.
</span><ins>+ * Copyright (C) 2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  *  This library is free software; you can redistribute it and/or
</span><span class="cx">  *  modify it under the terms of the GNU Lesser General Public
</span><span class="lines">@@ -49,14 +50,14 @@
</span><span class="cx">     m_page.userMediaPermissionRequestManager().cancelUserMediaRequest(request);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void WebUserMediaClient::checkUserMediaPermission(WebCore::UserMediaPermissionCheck&amp; request)
</del><ins>+void WebUserMediaClient::enumerateMediaDevices(MediaDevicesEnumerationRequest&amp; request)
</ins><span class="cx"> {
</span><del>-    m_page.userMediaPermissionRequestManager().startUserMediaPermissionCheck(request);
</del><ins>+    m_page.userMediaPermissionRequestManager().enumerateMediaDevices(request);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-void WebUserMediaClient::cancelUserMediaPermissionCheck(WebCore::UserMediaPermissionCheck&amp; request)
</del><ins>+void WebUserMediaClient::cancelMediaDevicesEnumerationRequest(MediaDevicesEnumerationRequest&amp; request)
</ins><span class="cx"> {
</span><del>-    m_page.userMediaPermissionRequestManager().cancelUserMediaPermissionCheck(request);
</del><ins>+    m_page.userMediaPermissionRequestManager().cancelMediaDevicesEnumeration(request);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> } // namespace WebKit;
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebCoreSupportWebUserMediaClienth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebUserMediaClient.h (207462 => 207463)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebUserMediaClient.h        2016-10-18 13:15:40 UTC (rev 207462)
+++ trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebUserMediaClient.h        2016-10-18 14:53:06 UTC (rev 207463)
</span><span class="lines">@@ -1,5 +1,6 @@
</span><span class="cx"> /*
</span><span class="cx">  * Copyright (C) 2014 Igalia S.L.
</span><ins>+ * Copyright (C) 2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  *  This library is free software; you can redistribute it and/or
</span><span class="cx">  *  modify it under the terms of the GNU Lesser General Public
</span><span class="lines">@@ -30,6 +31,7 @@
</span><span class="cx"> class WebUserMediaClient : public WebCore::UserMediaClient {
</span><span class="cx"> public:
</span><span class="cx">     WebUserMediaClient(WebPage&amp;);
</span><ins>+    ~WebUserMediaClient() { }
</ins><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     void pageDestroyed() override;
</span><span class="lines">@@ -37,8 +39,8 @@
</span><span class="cx">     void requestUserMediaAccess(WebCore::UserMediaRequest&amp;) override;
</span><span class="cx">     void cancelUserMediaAccessRequest(WebCore::UserMediaRequest&amp;) override;
</span><span class="cx"> 
</span><del>-    void checkUserMediaPermission(WebCore::UserMediaPermissionCheck&amp;) override;
-    void cancelUserMediaPermissionCheck(WebCore::UserMediaPermissionCheck&amp;) override;
</del><ins>+    void enumerateMediaDevices(WebCore::MediaDevicesEnumerationRequest&amp;) final;
+    void cancelMediaDevicesEnumerationRequest(WebCore::MediaDevicesEnumerationRequest&amp;) final;
</ins><span class="cx"> 
</span><span class="cx">     WebPage&amp; m_page;
</span><span class="cx"> };
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebPageWebPagecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/WebPage/WebPage.cpp (207462 => 207463)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebPage/WebPage.cpp        2016-10-18 13:15:40 UTC (rev 207462)
+++ trunk/Source/WebKit2/WebProcess/WebPage/WebPage.cpp        2016-10-18 14:53:06 UTC (rev 207463)
</span><span class="lines">@@ -3681,15 +3681,20 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(MEDIA_STREAM)
</span><del>-void WebPage::didReceiveUserMediaPermissionDecision(uint64_t userMediaID, bool allowed, const String&amp; audioDeviceUID, const String&amp; videoDeviceUID)
</del><ins>+void WebPage::userMediaAccessWasGranted(uint64_t userMediaID, const String&amp; audioDeviceUID, const String&amp; videoDeviceUID)
</ins><span class="cx"> {
</span><del>-    m_userMediaPermissionRequestManager.didReceiveUserMediaPermissionDecision(userMediaID, allowed, audioDeviceUID, videoDeviceUID);
</del><ins>+    m_userMediaPermissionRequestManager.userMediaAccessWasGranted(userMediaID, audioDeviceUID, videoDeviceUID);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-void WebPage::didCompleteUserMediaPermissionCheck(uint64_t userMediaID, const String&amp; mediaDeviceIdentifierHashSalt, bool allowed)
</del><ins>+void WebPage::userMediaAccessWasDenied(uint64_t userMediaID, uint64_t reason, String invalidConstraint)
</ins><span class="cx"> {
</span><del>-    m_userMediaPermissionRequestManager.didCompleteUserMediaPermissionCheck(userMediaID, mediaDeviceIdentifierHashSalt, allowed);
</del><ins>+    m_userMediaPermissionRequestManager.userMediaAccessWasDenied(userMediaID, static_cast&lt;UserMediaRequest::MediaAccessDenialReason&gt;(reason), invalidConstraint);
</ins><span class="cx"> }
</span><ins>+
+void WebPage::didCompleteMediaDeviceEnumeration(uint64_t userMediaID, const Vector&lt;CaptureDevice&gt;&amp; devices, const String&amp; deviceIdentifierHashSalt, bool originHasPersistentAccess)
+{
+    m_userMediaPermissionRequestManager.didCompleteMediaDeviceEnumeration(userMediaID, devices, deviceIdentifierHashSalt, originHasPersistentAccess);
+}
</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 (207462 => 207463)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h        2016-10-18 13:15:40 UTC (rev 207462)
+++ trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h        2016-10-18 14:53:06 UTC (rev 207463)
</span><span class="lines">@@ -1159,8 +1159,10 @@
</span><span class="cx">     void didReceiveNotificationPermissionDecision(uint64_t notificationID, bool allowed);
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(MEDIA_STREAM)
</span><del>-    void didReceiveUserMediaPermissionDecision(uint64_t userMediaID, bool allowed, const String&amp; audioDeviceUID, const String&amp; videoDeviceUID);
-    void didCompleteUserMediaPermissionCheck(uint64_t userMediaID, const String&amp;, bool allowed);
</del><ins>+    void userMediaAccessWasGranted(uint64_t userMediaID, const String&amp; audioDeviceUID, const String&amp; videoDeviceUID);
+    void userMediaAccessWasDenied(uint64_t userMediaID, uint64_t reason, String invalidConstraint);
+
+    void didCompleteMediaDeviceEnumeration(uint64_t userMediaID, const Vector&lt;WebCore::CaptureDevice&gt;&amp; devices, const String&amp; deviceIdentifierHashSalt, bool originHasPersistentAccess);
</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 (207462 => 207463)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebPage/WebPage.messages.in        2016-10-18 13:15:40 UTC (rev 207462)
+++ trunk/Source/WebKit2/WebProcess/WebPage/WebPage.messages.in        2016-10-18 14:53:06 UTC (rev 207463)
</span><span class="lines">@@ -288,8 +288,9 @@
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(MEDIA_STREAM)
</span><span class="cx">     # MediaSteam
</span><del>-    DidReceiveUserMediaPermissionDecision(uint64_t userMediaID, bool allowed, String audioDeviceUID, String videoDeviceUID)
-    DidCompleteUserMediaPermissionCheck(uint64_t userMediaID, String mediaDeviceIdentifierHashSalt, bool allowed)
</del><ins>+    UserMediaAccessWasGranted(uint64_t userMediaID, String audioDeviceUID, String videoDeviceUID)
+    UserMediaAccessWasDenied(uint64_t userMediaID, uint64_t reason, String invalidConstraint)
+    DidCompleteMediaDeviceEnumeration(uint64_t userMediaID, Vector&lt;WebCore::CaptureDevice&gt; devices, String mediaDeviceIdentifierHashSalt, bool hasPersistentAccess)
</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 (207462 => 207463)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/ChangeLog        2016-10-18 13:15:40 UTC (rev 207462)
+++ trunk/Tools/ChangeLog        2016-10-18 14:53:06 UTC (rev 207463)
</span><span class="lines">@@ -1,3 +1,15 @@
</span><ins>+2016-10-18  Eric Carlson  &lt;eric.carlson@apple.com&gt;
+
+        [MediaStream] Resolve constraints and enumerate devices in the UI process
+        https://bugs.webkit.org/show_bug.cgi?id=162147
+        &lt;rdar://problem/28803569&gt;
+
+        Reviewed by Darin Adler.
+
+        * WebKitTestRunner/TestController.cpp:
+        (WTR::TestController::resetPreferencesToConsistentValues): Enable mock capture devices.
+        (WTR::TestController::decidePolicyForUserMediaPermissionRequestIfPossible): Update for API changes.
+
</ins><span class="cx"> 2016-10-17  Megan Gardner  &lt;megan_gardner@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Add test and infrastructure for link popover
</span></span></pre></div>
<a id="trunkToolsWebKitTestRunnerTestControllercpp"></a>
<div class="modfile"><h4>Modified: trunk/Tools/WebKitTestRunner/TestController.cpp (207462 => 207463)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/WebKitTestRunner/TestController.cpp        2016-10-18 13:15:40 UTC (rev 207462)
+++ trunk/Tools/WebKitTestRunner/TestController.cpp        2016-10-18 14:53:06 UTC (rev 207463)
</span><span class="lines">@@ -686,6 +686,8 @@
</span><span class="cx"> 
</span><span class="cx">     WKCookieManagerDeleteAllCookies(WKContextGetCookieManager(m_context.get()));
</span><span class="cx"> 
</span><ins>+    WKPreferencesSetMockCaptureDevicesEnabled(preferences, true);
+
</ins><span class="cx">     platformResetPreferencesToConsistentValues();
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -1956,26 +1958,32 @@
</span><span class="cx">         if (settings)
</span><span class="cx">             persistentPermission = settings-&gt;persistentPermission();
</span><span class="cx"> 
</span><ins>+        if (!m_isUserMediaPermissionAllowed &amp;&amp; !persistentPermission) {
+            WKUserMediaPermissionRequestDeny(request, kWKPermissionDenied);
+            continue;
+        }
+
</ins><span class="cx">         WKRetainPtr&lt;WKArrayRef&gt; audioDeviceUIDs = WKUserMediaPermissionRequestAudioDeviceUIDs(request);
</span><span class="cx">         WKRetainPtr&lt;WKArrayRef&gt; videoDeviceUIDs = WKUserMediaPermissionRequestVideoDeviceUIDs(request);
</span><span class="cx"> 
</span><del>-        if ((m_isUserMediaPermissionAllowed || persistentPermission) &amp;&amp; (WKArrayGetSize(videoDeviceUIDs.get()) || WKArrayGetSize(audioDeviceUIDs.get()))) {
-            WKRetainPtr&lt;WKStringRef&gt; videoDeviceUID;
-            if (WKArrayGetSize(videoDeviceUIDs.get()))
-                videoDeviceUID = reinterpret_cast&lt;WKStringRef&gt;(WKArrayGetItemAtIndex(videoDeviceUIDs.get(), 0));
-            else
-                videoDeviceUID = WKStringCreateWithUTF8CString(&quot;&quot;);
</del><ins>+        if (!WKArrayGetSize(videoDeviceUIDs.get()) &amp;&amp; !WKArrayGetSize(audioDeviceUIDs.get())) {
+            WKUserMediaPermissionRequestDeny(request, kWKNoConstraints);
+            continue;
+        }
</ins><span class="cx"> 
</span><del>-            WKRetainPtr&lt;WKStringRef&gt; audioDeviceUID;
-            if (WKArrayGetSize(audioDeviceUIDs.get()))
-                audioDeviceUID = reinterpret_cast&lt;WKStringRef&gt;(WKArrayGetItemAtIndex(audioDeviceUIDs.get(), 0));
-            else
-                audioDeviceUID = WKStringCreateWithUTF8CString(&quot;&quot;);
</del><ins>+        WKRetainPtr&lt;WKStringRef&gt; videoDeviceUID;
+        if (WKArrayGetSize(videoDeviceUIDs.get()))
+            videoDeviceUID = reinterpret_cast&lt;WKStringRef&gt;(WKArrayGetItemAtIndex(videoDeviceUIDs.get(), 0));
+        else
+            videoDeviceUID = WKStringCreateWithUTF8CString(&quot;&quot;);
</ins><span class="cx"> 
</span><del>-            WKUserMediaPermissionRequestAllow(request, audioDeviceUID.get(), videoDeviceUID.get());
</del><ins>+        WKRetainPtr&lt;WKStringRef&gt; audioDeviceUID;
+        if (WKArrayGetSize(audioDeviceUIDs.get()))
+            audioDeviceUID = reinterpret_cast&lt;WKStringRef&gt;(WKArrayGetItemAtIndex(audioDeviceUIDs.get(), 0));
+        else
+            audioDeviceUID = WKStringCreateWithUTF8CString(&quot;&quot;);
</ins><span class="cx"> 
</span><del>-        } else
-            WKUserMediaPermissionRequestDeny(request);
</del><ins>+        WKUserMediaPermissionRequestAllow(request, audioDeviceUID.get(), videoDeviceUID.get());
</ins><span class="cx">     }
</span><span class="cx">     m_userMediaPermissionRequests.clear();
</span><span class="cx"> }
</span></span></pre>
</div>
</div>

</body>
</html>