<!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>[205348] 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/205348">205348</a></dd>
<dt>Author</dt> <dd>eric.carlson@apple.com</dd>
<dt>Date</dt> <dd>2016-09-02 10:36:29 -0700 (Fri, 02 Sep 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>[MediaStream] applyConstraints pt. 1 - mandatory constraints
https://bugs.webkit.org/show_bug.cgi?id=161469
&lt;rdar://problem/28109325&gt;

Reviewed by Jer Noble.

Source/WebCore:

Tests: fast/mediastream/apply-constraints-audio.html
       fast/mediastream/apply-constraints-video.html

* Modules/mediastream/MediaStreamTrack.cpp:
(WebCore::MediaStreamTrack::MediaStreamTrack): Initialize the weak pointer factory.
(WebCore::MediaStreamTrack::applyConstraints): Make it work.
* Modules/mediastream/MediaStreamTrack.h:
* Modules/mediastream/MediaStreamTrack.idl:

* WebCore.xcodeproj/project.pbxproj: Add JSMediaDevicesCustom.h.

* bindings/js/JSMediaDevicesCustom.cpp:
(WebCore::createStringConstraint): Add name parameter.
(WebCore::createBooleanConstraint): Ditto.
(WebCore::createDoubleConstraint): Ditto.
(WebCore::createIntConstraint): Ditto.
(WebCore::parseMediaTrackConstraintSetForKey): Drop type parameter because we don't need to
  filter by source media type.
(WebCore::parseAdvancedConstraints): Ditto.
(WebCore::parseMediaConstraintsDictionary): Renamed from parseConstraints.
(WebCore::JSMediaDevices::getUserMedia): Don't throw exceptions, always return a promise.
(WebCore::parseConstraints): Deleted.
* bindings/js/JSMediaDevicesCustom.h: Added.

* bindings/js/JSMediaStreamTrackCustom.cpp:
(WebCore::JSMediaStreamTrack::getSettings): Don't include aspect ratio if the value is 0.
(WebCore::capabilityValue): asULong -&gt; asInt.
(WebCore::JSMediaStreamTrack::applyConstraints): New.
(WebCore::JSMediaStreamTrack::getConstraints): New.

* bindings/js/WebCoreBuiltinNames.h: Add &quot;mediaStreamTrackConstraints&quot;.

* html/HTMLMediaElement.cpp:
(WebCore::HTMLMediaElement::setSrcObject): Drive by fix: don't call DOMURL::createPublicURL(null).

* platform/mediastream/MediaConstraints.cpp:
(WebCore::MediaConstraint::create): Pass name to constructors.
(WebCore::StringConstraint::find): New.
* platform/mediastream/MediaConstraints.h:

* platform/mediastream/MediaStreamTrackPrivate.cpp:
(WebCore::MediaStreamTrackPrivate::applyConstraints): Add callback parameters.
* platform/mediastream/MediaStreamTrackPrivate.h:

* platform/mediastream/RealtimeMediaSource.cpp:
(WebCore::RealtimeMediaSource::RealtimeMediaSource): Initialize weak pointer factory.
(WebCore::RealtimeMediaSource::settingsDidChange): Don't call observers immediately so we can
 coalesce multiple changes in the same runloop cycle.
(WebCore::RealtimeMediaSource::supportsConstraint): New.
(WebCore::value): Return the most appropriate value from a numeric constraint.
(WebCore::RealtimeMediaSource::applyConstraint): New, apply one constraint.
(WebCore::RealtimeMediaSource::applyConstraints): New, validate and apply constraints.
(WebCore::RealtimeMediaSource::setWidth): New.
(WebCore::RealtimeMediaSource::setHeight): New.
(WebCore::RealtimeMediaSource::setFrameRate): New.
(WebCore::RealtimeMediaSource::setAspectRatio): New.
(WebCore::RealtimeMediaSource::setFacingMode): New.
(WebCore::RealtimeMediaSource::setVolume): New.
(WebCore::RealtimeMediaSource::setSampleRate): New.
(WebCore::RealtimeMediaSource::setSampleSize): New.
(WebCore::RealtimeMediaSource::setEchoCancellation) New.:
(WebCore::RealtimeMediaSource::scheduleDeferredTask): New.
* platform/mediastream/RealtimeMediaSource.h:

* platform/mediastream/RealtimeMediaSourceCapabilities.h:
(WebCore::CapabilityValueOrRange::CapabilityValueOrRange): &quot;unsigned long&quot; -&gt; &quot;int&quot;

* platform/mediastream/RealtimeMediaSourceSettings.cpp:
(WebCore::userFacing): New.
(WebCore::environmentFacing): New.
(WebCore::leftFacing): New.
(WebCore::rightFacing): New.
(WebCore::RealtimeMediaSourceSettings::facingMode):
(WebCore::RealtimeMediaSourceSettings::videoFacingModeEnum):
* platform/mediastream/RealtimeMediaSourceSettings.h:

* platform/mediastream/mac/AVAudioCaptureSource.mm:
(WebCore::AVAudioCaptureSource::initializeCapabilities): Volume range is 0.0 .. 1.0.

* platform/mediastream/mac/AVMediaCaptureSource.h:
(WebCore::AVMediaCaptureSource::createWeakPtr): Deleted.
* platform/mediastream/mac/AVMediaCaptureSource.mm:
(WebCore::AVMediaCaptureSource::AVMediaCaptureSource): Don't need the weak ptr factory, it is
  in the base class.
(WebCore::AVMediaCaptureSource::scheduleDeferredTask): Deleted.

* platform/mediastream/mac/AVVideoCaptureSource.h:
* platform/mediastream/mac/AVVideoCaptureSource.mm:
(WebCore::AVVideoCaptureSource::applySize): New.
(WebCore::AVVideoCaptureSource::applyFrameRate): New.
(WebCore::AVVideoCaptureSource::setupCaptureSession):
(WebCore::AVVideoCaptureSource::setFrameRateConstraint): Deleted.
(WebCore::AVVideoCaptureSource::applyConstraints): Deleted.

* platform/mock/MockRealtimeAudioSource.cpp:
(WebCore::MockRealtimeAudioSource::updateSettings): Set volume and echoCancellation to the
  current values.
(WebCore::MockRealtimeAudioSource::initializeCapabilities): Volume takes a float, not an int.
* platform/mock/MockRealtimeAudioSource.h:

* platform/mock/MockRealtimeMediaSource.cpp: Minor cleanup.
* platform/mock/MockRealtimeMediaSource.h:

* platform/mock/MockRealtimeVideoSource.cpp:
(WebCore::MockRealtimeVideoSource::MockRealtimeVideoSource): Initialize frame rate.
(WebCore::MockRealtimeVideoSource::startProducingData): m_size -&gt; size().
(WebCore::MockRealtimeVideoSource::updateSettings): Use accessors because instance variables
  have been moved to the base class.
(WebCore::MockRealtimeVideoSource::initializeCapabilities): Ditto.
(WebCore::MockRealtimeVideoSource::applyFrameRate): New.
(WebCore::MockRealtimeVideoSource::applySize):
(WebCore::MockRealtimeVideoSource::drawAnimation):
(WebCore::MockRealtimeVideoSource::drawBoxes):
(WebCore::MockRealtimeVideoSource::drawText):
(WebCore::MockRealtimeVideoSource::generateFrame):
(WebCore::MockRealtimeVideoSource::imageBuffer):
(WebCore::MockRealtimeVideoSource::setFrameRate): Deleted.
(WebCore::MockRealtimeVideoSource::setSize): Deleted.
* platform/mock/MockRealtimeVideoSource.h:
(WebCore::MockRealtimeVideoSource::size): Deleted.

LayoutTests:

* fast/mediastream/apply-constraints-audio-expected.txt: Added.
* fast/mediastream/apply-constraints-audio.html: Added.
* fast/mediastream/apply-constraints-video-expected.txt: Added.
* fast/mediastream/apply-constraints-video.html: Added.
* fast/mediastream/resources/apply-constraints-utils.js: Added.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreModulesmediastreamMediaStreamTrackcpp">trunk/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesmediastreamMediaStreamTrackh">trunk/Source/WebCore/Modules/mediastream/MediaStreamTrack.h</a></li>
<li><a href="#trunkSourceWebCoreModulesmediastreamMediaStreamTrackidl">trunk/Source/WebCore/Modules/mediastream/MediaStreamTrack.idl</a></li>
<li><a href="#trunkSourceWebCoreWebCorexcodeprojprojectpbxproj">trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceWebCorebindingsjsJSMediaDevicesCustomcpp">trunk/Source/WebCore/bindings/js/JSMediaDevicesCustom.cpp</a></li>
<li><a href="#trunkSourceWebCorebindingsjsJSMediaStreamTrackCustomcpp">trunk/Source/WebCore/bindings/js/JSMediaStreamTrackCustom.cpp</a></li>
<li><a href="#trunkSourceWebCorebindingsjsWebCoreBuiltinNamesh">trunk/Source/WebCore/bindings/js/WebCoreBuiltinNames.h</a></li>
<li><a href="#trunkSourceWebCorehtmlHTMLMediaElementcpp">trunk/Source/WebCore/html/HTMLMediaElement.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsavfoundationobjcMediaPlayerPrivateMediaStreamAVFObjCmm">trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.mm</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="#trunkSourceWebCoreplatformmediastreamMediaStreamTrackPrivatecpp">trunk/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformmediastreamMediaStreamTrackPrivateh">trunk/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h</a></li>
<li><a href="#trunkSourceWebCoreplatformmediastreamRealtimeMediaSourcecpp">trunk/Source/WebCore/platform/mediastream/RealtimeMediaSource.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformmediastreamRealtimeMediaSourceh">trunk/Source/WebCore/platform/mediastream/RealtimeMediaSource.h</a></li>
<li><a href="#trunkSourceWebCoreplatformmediastreamRealtimeMediaSourceCapabilitiesh">trunk/Source/WebCore/platform/mediastream/RealtimeMediaSourceCapabilities.h</a></li>
<li><a href="#trunkSourceWebCoreplatformmediastreamRealtimeMediaSourceSettingscpp">trunk/Source/WebCore/platform/mediastream/RealtimeMediaSourceSettings.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformmediastreamRealtimeMediaSourceSettingsh">trunk/Source/WebCore/platform/mediastream/RealtimeMediaSourceSettings.h</a></li>
<li><a href="#trunkSourceWebCoreplatformmediastreammacAVAudioCaptureSourcemm">trunk/Source/WebCore/platform/mediastream/mac/AVAudioCaptureSource.mm</a></li>
<li><a href="#trunkSourceWebCoreplatformmediastreammacAVMediaCaptureSourceh">trunk/Source/WebCore/platform/mediastream/mac/AVMediaCaptureSource.h</a></li>
<li><a href="#trunkSourceWebCoreplatformmediastreammacAVMediaCaptureSourcemm">trunk/Source/WebCore/platform/mediastream/mac/AVMediaCaptureSource.mm</a></li>
<li><a href="#trunkSourceWebCoreplatformmediastreammacAVVideoCaptureSourceh">trunk/Source/WebCore/platform/mediastream/mac/AVVideoCaptureSource.h</a></li>
<li><a href="#trunkSourceWebCoreplatformmediastreammacAVVideoCaptureSourcemm">trunk/Source/WebCore/platform/mediastream/mac/AVVideoCaptureSource.mm</a></li>
<li><a href="#trunkSourceWebCoreplatformmockMockRealtimeAudioSourcecpp">trunk/Source/WebCore/platform/mock/MockRealtimeAudioSource.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformmockMockRealtimeAudioSourceh">trunk/Source/WebCore/platform/mock/MockRealtimeAudioSource.h</a></li>
<li><a href="#trunkSourceWebCoreplatformmockMockRealtimeMediaSourcecpp">trunk/Source/WebCore/platform/mock/MockRealtimeMediaSource.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformmockMockRealtimeMediaSourceh">trunk/Source/WebCore/platform/mock/MockRealtimeMediaSource.h</a></li>
<li><a href="#trunkSourceWebCoreplatformmockMockRealtimeVideoSourcecpp">trunk/Source/WebCore/platform/mock/MockRealtimeVideoSource.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformmockMockRealtimeVideoSourceh">trunk/Source/WebCore/platform/mock/MockRealtimeVideoSource.h</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsfastmediastreamapplyconstraintsaudioexpectedtxt">trunk/LayoutTests/fast/mediastream/apply-constraints-audio-expected.txt</a></li>
<li><a href="#trunkLayoutTestsfastmediastreamapplyconstraintsaudiohtml">trunk/LayoutTests/fast/mediastream/apply-constraints-audio.html</a></li>
<li><a href="#trunkLayoutTestsfastmediastreamapplyconstraintsvideoexpectedtxt">trunk/LayoutTests/fast/mediastream/apply-constraints-video-expected.txt</a></li>
<li><a href="#trunkLayoutTestsfastmediastreamapplyconstraintsvideohtml">trunk/LayoutTests/fast/mediastream/apply-constraints-video.html</a></li>
<li><a href="#trunkLayoutTestsfastmediastreamresourcesapplyconstraintsutilsjs">trunk/LayoutTests/fast/mediastream/resources/apply-constraints-utils.js</a></li>
<li><a href="#trunkSourceWebCorebindingsjsJSMediaDevicesCustomh">trunk/Source/WebCore/bindings/js/JSMediaDevicesCustom.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (205347 => 205348)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2016-09-02 17:28:00 UTC (rev 205347)
+++ trunk/LayoutTests/ChangeLog        2016-09-02 17:36:29 UTC (rev 205348)
</span><span class="lines">@@ -1,3 +1,17 @@
</span><ins>+2016-09-02  Eric Carlson  &lt;eric.carlson@apple.com&gt;
+
+        [MediaStream] applyConstraints pt. 1 - mandatory constraints
+        https://bugs.webkit.org/show_bug.cgi?id=161469
+        &lt;rdar://problem/28109325&gt;
+
+        Reviewed by Jer Noble.
+
+        * fast/mediastream/apply-constraints-audio-expected.txt: Added.
+        * fast/mediastream/apply-constraints-audio.html: Added.
+        * fast/mediastream/apply-constraints-video-expected.txt: Added.
+        * fast/mediastream/apply-constraints-video.html: Added.
+        * fast/mediastream/resources/apply-constraints-utils.js: Added.
+
</ins><span class="cx"> 2016-09-01  Ryosuke Niwa  &lt;rniwa@webkit.org&gt;
</span><span class="cx"> 
</span><span class="cx">         Only update connected custom elements
</span></span></pre></div>
<a id="trunkLayoutTestsfastmediastreamapplyconstraintsaudioexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/mediastream/apply-constraints-audio-expected.txt (0 => 205348)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/mediastream/apply-constraints-audio-expected.txt                                (rev 0)
+++ trunk/LayoutTests/fast/mediastream/apply-constraints-audio-expected.txt        2016-09-02 17:36:29 UTC (rev 205348)
</span><span class="lines">@@ -0,0 +1,43 @@
</span><ins>+Tests applyConstraints on an audio stream track.
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+PASS stream.getVideoTracks().length is 0
+PASS stream.getAudioTracks().length is 1
+PASS video.videoTracks.length is 0
+PASS video.audioTracks.length is 1
+
+** Constraint: {&quot;volume&quot;:0.5} - set volume to a valid value.
+PASS settings['volume'] is 0.5
+PASS typeof settings['echoCancellation'] is 'boolean'
+PASS settings['echoCancellation'] is false
+
+** Constraint: {&quot;volume&quot;:{&quot;exact&quot;:2.1}} - the 'exact' constraint it too big, promise should reject and no settings should change.
+PASS Promise was rejected
+PASS error.constraint is &quot;volume&quot;
+PASS settings['volume'] is 0.5
+PASS typeof settings['echoCancellation'] is 'boolean'
+PASS settings['echoCancellation'] is false
+
+** Constraint: {&quot;volume&quot;:{&quot;exact&quot;:-1}} - the 'exact' constraint it too small, promise should reject and no settings should change.
+PASS Promise was rejected
+PASS error.constraint is &quot;volume&quot;
+PASS settings['volume'] is 0.5
+PASS typeof settings['echoCancellation'] is 'boolean'
+PASS settings['echoCancellation'] is false
+
+** Constraint: {&quot;echoCancellation&quot;:true} - set echoCancellation to a valid value.
+PASS settings['volume'] is 0.5
+PASS typeof settings['echoCancellation'] is 'boolean'
+PASS settings['echoCancellation'] is true
+
+** Constraint: {&quot;facingMode&quot;:&quot;environment&quot;,&quot;frameRate&quot;:30,&quot;volume&quot;:1} - constraint not supported by an audio track should be ignored.
+PASS settings['volume'] is 1
+PASS typeof settings['echoCancellation'] is 'boolean'
+PASS settings['echoCancellation'] is true
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestsfastmediastreamapplyconstraintsaudiohtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/mediastream/apply-constraints-audio.html (0 => 205348)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/mediastream/apply-constraints-audio.html                                (rev 0)
+++ trunk/LayoutTests/fast/mediastream/apply-constraints-audio.html        2016-09-02 17:36:29 UTC (rev 205348)
</span><span class="lines">@@ -0,0 +1,63 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+    &lt;head&gt;
+        &lt;script src=&quot;../../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
+        &lt;script src=&quot;resources/apply-constraints-utils.js&quot;&gt;&lt;/script&gt;
+        &lt;script&gt;
+
+            let tests = [
+                {
+                    message: &quot;set volume to a valid value.&quot;,
+                    constraint: { volume: .5 }, 
+                    expected: { volume: .5, echoCancellation: false }, 
+                },
+                {
+                    message: &quot;the 'exact' constraint it too big, promise should reject and no settings should change.&quot;,
+                    constraint: { volume: { exact: 2.1 } }, 
+                    expected: { volume: .5, echoCancellation: false }, 
+                    error: &quot;volume&quot;,
+                },
+                {
+                    message: &quot;the 'exact' constraint it too small, promise should reject and no settings should change.&quot;,
+                    constraint: { volume: { exact: -1 } }, 
+                    expected: { volume: .5, echoCancellation: false }, 
+                    error: &quot;volume&quot;,
+                },
+                {
+                    message: &quot;set echoCancellation to a valid value.&quot;,
+                    constraint: { echoCancellation: true }, 
+                    expected: { volume: .5, echoCancellation: true }, 
+                },
+                {
+                    message: &quot;constraint not supported by an audio track should be ignored.&quot;,
+                    constraint: { facingMode: &quot;environment&quot;, frameRate: 30, volume: 1.0 }, 
+                    expected: { volume: 1.0, echoCancellation: true }, 
+                },
+                
+            ];
+
+            let tester = new ConstraintsTest({ audio: true }, tests, &quot;Tests applyConstraints on an audio stream track.&quot;)
+                .onStreamReady((s) =&gt; {
+                    stream = s;
+                    shouldBe('stream.getVideoTracks().length', '0');
+                    shouldBe('stream.getAudioTracks().length', '1');
+                    tester.setStreamTrack(stream.getAudioTracks()[0]);
+                })
+                .onVideoReady((v) =&gt; {
+                    video = v;
+                    shouldBe('video.videoTracks.length', '0');
+                    shouldBe('video.audioTracks.length', '1');
+                })
+                .start();
+
+        &lt;/script&gt;
+        &lt;script src=&quot;../../resources/js-test-post.js&quot;&gt;&lt;/script&gt;
+    &lt;/head&gt;
+    &lt;body&gt;
+        &lt;video controls id=&quot;video&quot;&lt;/video&gt;
+        &lt;br&gt;
+        &lt;div id=&quot;div&quot;&gt;&lt;/div&gt;
+
+    &lt;/body&gt;
+&lt;/html&gt;
+
</ins></span></pre></div>
<a id="trunkLayoutTestsfastmediastreamapplyconstraintsvideoexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/mediastream/apply-constraints-video-expected.txt (0 => 205348)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/mediastream/apply-constraints-video-expected.txt                                (rev 0)
+++ trunk/LayoutTests/fast/mediastream/apply-constraints-video-expected.txt        2016-09-02 17:36:29 UTC (rev 205348)
</span><span class="lines">@@ -0,0 +1,97 @@
</span><ins>+Tests applyConstraints on a video stream track.
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+PASS stream.getVideoTracks().length is 1
+PASS stream.getAudioTracks().length is 0
+PASS video.videoTracks.length is 1
+PASS video.audioTracks.length is 0
+
+** Constraint: {&quot;width&quot;:640,&quot;height&quot;:480,&quot;frameRate&quot;:30} - set width, height, and frame rate to valid values.
+PASS settings['width'] is 640
+PASS settings['height'] is 480
+PASS settings['frameRate'] is 30
+
+** Constraint: {&quot;width&quot;:320,&quot;height&quot;:240} - change width and height, frame rate should remain unchanged.
+PASS settings['width'] is 320
+PASS settings['height'] is 240
+PASS settings['frameRate'] is 30
+
+** Constraint: {&quot;width&quot;:{&quot;exact&quot;:2000}} - the 'exact' constraint can't be satisfied, promise should reject and no settings should change.
+PASS Promise was rejected
+PASS error.constraint is &quot;width&quot;
+PASS settings['width'] is 320
+PASS settings['height'] is 240
+PASS settings['frameRate'] is 30
+
+** Constraint: {&quot;width&quot;:640,&quot;height&quot;:{&quot;min&quot;:3000}} - the 'min' constraint can't be satisfied, promise should reject and no settings should change.
+PASS Promise was rejected
+PASS error.constraint is &quot;height&quot;
+PASS settings['width'] is 320
+PASS settings['height'] is 240
+PASS settings['frameRate'] is 30
+
+** Constraint: {&quot;frameRate&quot;:{&quot;max&quot;:6}} - the 'max' constraint can't be satisfied, promise should reject and no settings should change.
+PASS Promise was rejected
+PASS error.constraint is &quot;frameRate&quot;
+PASS settings['frameRate'] is 30
+
+** Constraint: {&quot;width&quot;:{&quot;exact&quot;:400}} - the 'exact' constraint can be satisfied.
+PASS settings['width'] is 400
+PASS settings['height'] is 240
+
+** Constraint: {&quot;width&quot;:{&quot;min&quot;:300,&quot;ideal&quot;:5000}} - the 'ideal' constraint can't be satisfied but the 'min' can, max should be chosen.
+PASS settings['width'] is 1920
+PASS settings['height'] is 240
+
+** Constraint: {&quot;width&quot;:{&quot;min&quot;:320,&quot;ideal&quot;:1280},&quot;height&quot;:{&quot;min&quot;:480,&quot;ideal&quot;:720}} - 'ideal' and 'min' constraints can be satisfied, 'ideal' should be chosen.
+PASS settings['width'] is 1280
+PASS settings['height'] is 720
+
+** Constraint: {&quot;width&quot;:3000} - ideal width is greater than track capability, should be clamped to the maximum value.
+PASS settings['width'] is 1920
+
+** Constraint: {&quot;width&quot;:160,&quot;height&quot;:120,&quot;frameRate&quot;:10} - all values are less than track capabilities, should be clamped to the minimum values.
+PASS settings['width'] is 320
+PASS settings['height'] is 240
+PASS settings['frameRate'] is 15
+
+** Constraint: {&quot;facingMode&quot;:&quot;environment&quot;} - set facing mode, width and height should remain unchanged
+PASS settings['width'] is 320
+PASS settings['height'] is 240
+PASS settings['facingMode'] is &quot;environment&quot;
+
+** Constraint: {&quot;facingMode&quot;:&quot;USER&quot;,&quot;height&quot;:400} - illegal facing mode value should be ignored, height should change.
+PASS settings['facingMode'] is &quot;environment&quot;
+PASS settings['width'] is 320
+PASS settings['height'] is 400
+
+** Constraint: {&quot;FACINGMODE&quot;:&quot;user&quot;,&quot;frameRate&quot;:30} - unknown constraint should be ignored, frame rate should change.
+PASS settings['facingMode'] is &quot;environment&quot;
+PASS settings['frameRate'] is 30
+
+** Constraint: {&quot;aspectRatio&quot;:&quot;1.3333&quot;} - aspect ratio should change width and height.
+PASS settings['width'] is 320
+PASS settings['height'] is 240
+
+** Constraint: {&quot;aspectRatio&quot;:&quot;1.7778&quot;} - new aspect ratio should again change width and height.
+PASS settings['width'] is 320
+PASS settings['height'] is 180
+
+** Constraint: {&quot;width&quot;:1920} - when aspect ratio has been set, changing width should change height.
+PASS settings['width'] is 1920
+PASS settings['height'] is 1080
+
+** Constraint: {&quot;height&quot;:576} - when aspect ratio has been set, changing height should change width.
+PASS settings['width'] is 1024
+PASS settings['height'] is 576
+
+** Constraint: {&quot;deviceId&quot;:{&quot;exact&quot;:&quot;20983-20o198-109283-098-09812&quot;}} - the 'exact' deviceID doesn't match, promise should reject.
+PASS Promise was rejected
+PASS error.constraint is &quot;deviceId&quot;
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestsfastmediastreamapplyconstraintsvideohtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/mediastream/apply-constraints-video.html (0 => 205348)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/mediastream/apply-constraints-video.html                                (rev 0)
+++ trunk/LayoutTests/fast/mediastream/apply-constraints-video.html        2016-09-02 17:36:29 UTC (rev 205348)
</span><span class="lines">@@ -0,0 +1,129 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+    &lt;head&gt;
+        &lt;script src=&quot;../../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
+        &lt;script src=&quot;resources/apply-constraints-utils.js&quot;&gt;&lt;/script&gt;
+        &lt;script&gt;
+
+            let tests = [
+                {
+                    message: &quot;set width, height, and frame rate to valid values.&quot;,
+                    constraint: { width: 640, height: 480, frameRate: 30 }, 
+                    expected: { width: 640, height: 480, frameRate: 30 }, 
+                },
+                {
+                    message: &quot;change width and height, frame rate should remain unchanged.&quot;,
+                    constraint: { width: 320, height: 240 }, 
+                    expected: { width: 320, height: 240, frameRate: 30 }, 
+                },
+                {
+                    message: &quot;the 'exact' constraint can't be satisfied, promise should reject and no settings should change.&quot;,
+                    constraint: { width: { exact: 2000 } }, 
+                    expected: { width: 320, height: 240, frameRate: 30 },
+                    error: &quot;width&quot;,
+                },
+                {
+                    message: &quot;the 'min' constraint can't be satisfied, promise should reject and no settings should change.&quot;,
+                    constraint: { width: 640, height: {min: 3000}, }, 
+                    expected: { width: 320, height: 240, frameRate: 30 },
+                    error: &quot;height&quot;,
+                },
+                {
+                    message: &quot;the 'max' constraint can't be satisfied, promise should reject and no settings should change.&quot;,
+                    constraint: { frameRate: {max: 6}, }, 
+                    expected: { frameRate: 30 },
+                    error: &quot;frameRate&quot;,
+                },
+                {
+                    message: &quot;the 'exact' constraint can be satisfied.&quot;,
+                    constraint: { width: { exact: 400 } }, 
+                    expected: { width: 400, height: 240 },
+                },
+                {
+                    message: &quot;the 'ideal' constraint can't be satisfied but the 'min' can, max should be chosen.&quot;,
+                    constraint: { width: {min: 300, ideal: 5000} }, 
+                    expected: { width: 1920, height: 240 },
+                },
+                {
+                    message: &quot;'ideal' and 'min' constraints can be satisfied, 'ideal' should be chosen.&quot;,
+                    constraint: { width: {min: 320, ideal: 1280}, height: {min: 480, ideal: 720}, }, 
+                    expected: { width: 1280, height: 720 },
+                },
+                {
+                    message: &quot;ideal width is greater than track capability, should be clamped to the maximum value.&quot;,
+                    constraint: { width: 3000 }, 
+                    expected: { width: 1920},
+                },
+                {
+                    message: &quot;all values are less than track capabilities, should be clamped to the minimum values.&quot;,
+                    constraint: { width: 160, height: 120, frameRate: 10 }, 
+                    expected: { width: 320, height: 240, frameRate: 15 },
+                },
+                {
+                    message: &quot;set facing mode, width and height should remain unchanged&quot;,
+                    constraint: { facingMode: &quot;environment&quot; }, 
+                    expected: { width: 320, height: 240, facingMode: &quot;environment&quot; },
+                },
+                {
+                    message: &quot;illegal facing mode value should be ignored, height should change.&quot;,
+                    constraint: { facingMode: &quot;USER&quot;, height: 400 }, 
+                    expected: { facingMode: &quot;environment&quot;, width: 320, height: 400 },
+                },
+                {
+                    message: &quot;unknown constraint should be ignored, frame rate should change.&quot;,
+                    constraint: { FACINGMODE: &quot;user&quot;, frameRate: 30 }, 
+                    expected: { facingMode: &quot;environment&quot;, frameRate: 30 },
+                },
+                {
+                    message: &quot;aspect ratio should change width and height.&quot;,
+                    constraint: { aspectRatio: (4/3).toFixed(4) }, 
+                    expected: { width: 320, height: 240 },
+                },
+                {
+                    message: &quot;new aspect ratio should again change width and height.&quot;,
+                    constraint: { aspectRatio: (16/9).toFixed(4) }, 
+                    expected: { width: 320, height: 180 },
+                },
+                {
+                    message: &quot;when aspect ratio has been set, changing width should change height.&quot;,
+                    constraint: { width: 1920 }, 
+                    expected: { width: 1920, height: 1080},
+                },
+                {
+                    message: &quot;when aspect ratio has been set, changing height should change width.&quot;,
+                    constraint: { height: 576 }, 
+                    expected: { width: 1024, height: 576},
+                },
+                {
+                    message: &quot;the 'exact' deviceID doesn't match, promise should reject.&quot;,
+                    constraint: { deviceId: {exact: &quot;20983-20o198-109283-098-09812&quot;}, }, 
+                    expected: { },
+                    error: &quot;deviceId&quot;,
+                },
+            ];
+
+            let tester = new ConstraintsTest({ video: true }, tests, &quot;Tests applyConstraints on a video stream track.&quot;)
+                .onStreamReady((s) =&gt; {
+                    stream = s;
+                    shouldBe('stream.getVideoTracks().length', '1');
+                    shouldBe('stream.getAudioTracks().length', '0');
+                    tester.setStreamTrack(stream.getVideoTracks()[0]);
+                })
+                .onVideoReady((v) =&gt; {
+                    video = v;
+                    shouldBe('video.videoTracks.length', '1');
+                    shouldBe('video.audioTracks.length', '0');
+                })
+                .start();
+
+        &lt;/script&gt;
+        &lt;script src=&quot;../../resources/js-test-post.js&quot;&gt;&lt;/script&gt;
+    &lt;/head&gt;
+    &lt;body&gt;
+        &lt;video controls id=&quot;video&quot;&lt;/video&gt;
+        &lt;br&gt;
+        &lt;div id=&quot;div&quot;&gt;&lt;/div&gt;
+
+    &lt;/body&gt;
+&lt;/html&gt;
+
</ins></span></pre></div>
<a id="trunkLayoutTestsfastmediastreamresourcesapplyconstraintsutilsjs"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/mediastream/resources/apply-constraints-utils.js (0 => 205348)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/mediastream/resources/apply-constraints-utils.js                                (rev 0)
+++ trunk/LayoutTests/fast/mediastream/resources/apply-constraints-utils.js        2016-09-02 17:36:29 UTC (rev 205348)
</span><span class="lines">@@ -0,0 +1,115 @@
</span><ins>+let settings;
+let error;
+
+ConstraintsTest = class ConstraintsTest {
+
+    constructor(constraints, tests, description)
+    {
+        this.constraints = constraints;
+        this.tests = tests;
+        this.description = description;
+
+        window.jsTestIsAsync = true;
+        window.successfullyParsed = true;
+        if (window.testRunner)
+            testRunner.setUserMediaPermission(true);
+    }
+
+    onStreamReady(callback)
+    {
+        if (typeof callback == &quot;function&quot;)
+            this.streamCallback = callback;
+        return this;
+    }
+
+    onVideoReady(callback)
+    {
+        if (typeof callback == &quot;function&quot;)
+            this.videoCallback = callback;
+        return this;
+    }
+
+    scheduleNextTest()
+    {
+        new Promise(resolved =&gt; this.runNextTest()); 
+    }
+
+    checkTrackSettings()
+    {
+        settings = this.track.getSettings();
+        for (let property in this.currentTest.expected) {
+            let expected = this.currentTest.expected[property];
+            if (typeof expected === &quot;string&quot;)
+                shouldBeEqualToString(`settings['${property}']`, expected);
+            else
+                shouldEvaluateTo(`settings['${property}']`, expected);
+        }
+    }
+
+    runNextTest()
+    {
+        description(this.description);
+
+        debug(&quot;&quot;);
+        if (!this.tests.length) {
+            finishJSTest();
+            return;
+        }
+
+        this.currentTest = this.tests.shift();
+        debug(`** Constraint: ${JSON.stringify(this.currentTest.constraint)} - ${this.currentTest.message}`);
+        this.track.applyConstraints(this.currentTest.constraint)
+            .then(() =&gt; {
+                if (this.currentTest.error)
+                    testFailed(`Constraint '${this.currentTest.error}' should have failed to apply, is '${settings[this.currentTest.error]}'`);
+                else
+                    this.checkTrackSettings()
+                this.scheduleNextTest();
+            })
+            .catch((evt) =&gt; {
+                if (!this.currentTest.error) {
+                    testFailed(&quot;Promise was rejected&quot;);
+                    testFailed(`Constraint failed to apply: ${evt} - constraint = ${evt.constraint}`);
+                } else {
+                    testPassed(&quot;Promise was rejected&quot;);
+                    error = evt;
+                    shouldBeEqualToString(&quot;error.constraint&quot;, this.currentTest.error);
+                }
+                this.checkTrackSettings()
+                this.scheduleNextTest();
+            });
+    }
+    
+    setStreamTrack(track)
+    {
+        this.track = track;
+    }
+
+    start()
+    {
+        window.addEventListener(&quot;load&quot;, function () {
+
+            navigator.mediaDevices.getUserMedia(this.constraints)
+                .then(stream =&gt; {
+                    this.video = document.querySelector(&quot;video&quot;);
+                    this.video.srcObject = stream;
+                    if (this.streamCallback)
+                        this.streamCallback(stream);
+                })
+                .then(() =&gt; new Promise(resolve =&gt; this.video.onloadedmetadata = resolve))
+                .then(() =&gt; {
+                    if (this.videoCallback)
+                        this.videoCallback(this.video);
+                    this.runNextTest();
+                })
+                .catch(err =&gt; {
+                    testFailed(`Stream setup failed with error: ${err}`);
+                    finishJSTest();
+                });
+
+        }.bind(this), false);
+
+        return this;
+    }
+
+}
</ins></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (205347 => 205348)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2016-09-02 17:28:00 UTC (rev 205347)
+++ trunk/Source/WebCore/ChangeLog        2016-09-02 17:36:29 UTC (rev 205348)
</span><span class="lines">@@ -1,3 +1,132 @@
</span><ins>+2016-09-02  Eric Carlson  &lt;eric.carlson@apple.com&gt;
+
+        [MediaStream] applyConstraints pt. 1 - mandatory constraints
+        https://bugs.webkit.org/show_bug.cgi?id=161469
+        &lt;rdar://problem/28109325&gt;
+
+        Reviewed by Jer Noble.
+
+        Tests: fast/mediastream/apply-constraints-audio.html
+               fast/mediastream/apply-constraints-video.html
+
+        * Modules/mediastream/MediaStreamTrack.cpp:
+        (WebCore::MediaStreamTrack::MediaStreamTrack): Initialize the weak pointer factory.
+        (WebCore::MediaStreamTrack::applyConstraints): Make it work.
+        * Modules/mediastream/MediaStreamTrack.h:
+        * Modules/mediastream/MediaStreamTrack.idl:
+
+        * WebCore.xcodeproj/project.pbxproj: Add JSMediaDevicesCustom.h.
+
+        * bindings/js/JSMediaDevicesCustom.cpp:
+        (WebCore::createStringConstraint): Add name parameter.
+        (WebCore::createBooleanConstraint): Ditto.
+        (WebCore::createDoubleConstraint): Ditto.
+        (WebCore::createIntConstraint): Ditto.
+        (WebCore::parseMediaTrackConstraintSetForKey): Drop type parameter because we don't need to
+          filter by source media type.
+        (WebCore::parseAdvancedConstraints): Ditto.
+        (WebCore::parseMediaConstraintsDictionary): Renamed from parseConstraints.
+        (WebCore::JSMediaDevices::getUserMedia): Don't throw exceptions, always return a promise.
+        (WebCore::parseConstraints): Deleted.
+        * bindings/js/JSMediaDevicesCustom.h: Added.
+
+        * bindings/js/JSMediaStreamTrackCustom.cpp:
+        (WebCore::JSMediaStreamTrack::getSettings): Don't include aspect ratio if the value is 0.
+        (WebCore::capabilityValue): asULong -&gt; asInt.
+        (WebCore::JSMediaStreamTrack::applyConstraints): New.
+        (WebCore::JSMediaStreamTrack::getConstraints): New.
+
+        * bindings/js/WebCoreBuiltinNames.h: Add &quot;mediaStreamTrackConstraints&quot;.
+
+        * html/HTMLMediaElement.cpp:
+        (WebCore::HTMLMediaElement::setSrcObject): Drive by fix: don't call DOMURL::createPublicURL(null).
+
+        * platform/mediastream/MediaConstraints.cpp:
+        (WebCore::MediaConstraint::create): Pass name to constructors.
+        (WebCore::StringConstraint::find): New.
+        * platform/mediastream/MediaConstraints.h:
+
+        * platform/mediastream/MediaStreamTrackPrivate.cpp:
+        (WebCore::MediaStreamTrackPrivate::applyConstraints): Add callback parameters.
+        * platform/mediastream/MediaStreamTrackPrivate.h:
+
+        * platform/mediastream/RealtimeMediaSource.cpp:
+        (WebCore::RealtimeMediaSource::RealtimeMediaSource): Initialize weak pointer factory.
+        (WebCore::RealtimeMediaSource::settingsDidChange): Don't call observers immediately so we can
+         coalesce multiple changes in the same runloop cycle.
+        (WebCore::RealtimeMediaSource::supportsConstraint): New.
+        (WebCore::value): Return the most appropriate value from a numeric constraint.
+        (WebCore::RealtimeMediaSource::applyConstraint): New, apply one constraint.
+        (WebCore::RealtimeMediaSource::applyConstraints): New, validate and apply constraints.
+        (WebCore::RealtimeMediaSource::setWidth): New.
+        (WebCore::RealtimeMediaSource::setHeight): New.
+        (WebCore::RealtimeMediaSource::setFrameRate): New.
+        (WebCore::RealtimeMediaSource::setAspectRatio): New.
+        (WebCore::RealtimeMediaSource::setFacingMode): New.
+        (WebCore::RealtimeMediaSource::setVolume): New.
+        (WebCore::RealtimeMediaSource::setSampleRate): New.
+        (WebCore::RealtimeMediaSource::setSampleSize): New.
+        (WebCore::RealtimeMediaSource::setEchoCancellation) New.:
+        (WebCore::RealtimeMediaSource::scheduleDeferredTask): New.
+        * platform/mediastream/RealtimeMediaSource.h:
+
+        * platform/mediastream/RealtimeMediaSourceCapabilities.h:
+        (WebCore::CapabilityValueOrRange::CapabilityValueOrRange): &quot;unsigned long&quot; -&gt; &quot;int&quot;
+
+        * platform/mediastream/RealtimeMediaSourceSettings.cpp:
+        (WebCore::userFacing): New.
+        (WebCore::environmentFacing): New.
+        (WebCore::leftFacing): New.
+        (WebCore::rightFacing): New.
+        (WebCore::RealtimeMediaSourceSettings::facingMode):
+        (WebCore::RealtimeMediaSourceSettings::videoFacingModeEnum):
+        * platform/mediastream/RealtimeMediaSourceSettings.h:
+
+        * platform/mediastream/mac/AVAudioCaptureSource.mm:
+        (WebCore::AVAudioCaptureSource::initializeCapabilities): Volume range is 0.0 .. 1.0.
+
+        * platform/mediastream/mac/AVMediaCaptureSource.h:
+        (WebCore::AVMediaCaptureSource::createWeakPtr): Deleted.
+        * platform/mediastream/mac/AVMediaCaptureSource.mm:
+        (WebCore::AVMediaCaptureSource::AVMediaCaptureSource): Don't need the weak ptr factory, it is
+          in the base class.
+        (WebCore::AVMediaCaptureSource::scheduleDeferredTask): Deleted.
+
+        * platform/mediastream/mac/AVVideoCaptureSource.h:
+        * platform/mediastream/mac/AVVideoCaptureSource.mm:
+        (WebCore::AVVideoCaptureSource::applySize): New.
+        (WebCore::AVVideoCaptureSource::applyFrameRate): New.
+        (WebCore::AVVideoCaptureSource::setupCaptureSession):
+        (WebCore::AVVideoCaptureSource::setFrameRateConstraint): Deleted.
+        (WebCore::AVVideoCaptureSource::applyConstraints): Deleted.
+
+        * platform/mock/MockRealtimeAudioSource.cpp:
+        (WebCore::MockRealtimeAudioSource::updateSettings): Set volume and echoCancellation to the
+          current values.
+        (WebCore::MockRealtimeAudioSource::initializeCapabilities): Volume takes a float, not an int.
+        * platform/mock/MockRealtimeAudioSource.h:
+
+        * platform/mock/MockRealtimeMediaSource.cpp: Minor cleanup.
+        * platform/mock/MockRealtimeMediaSource.h:
+
+        * platform/mock/MockRealtimeVideoSource.cpp:
+        (WebCore::MockRealtimeVideoSource::MockRealtimeVideoSource): Initialize frame rate.
+        (WebCore::MockRealtimeVideoSource::startProducingData): m_size -&gt; size().
+        (WebCore::MockRealtimeVideoSource::updateSettings): Use accessors because instance variables
+          have been moved to the base class.
+        (WebCore::MockRealtimeVideoSource::initializeCapabilities): Ditto.
+        (WebCore::MockRealtimeVideoSource::applyFrameRate): New.
+        (WebCore::MockRealtimeVideoSource::applySize):
+        (WebCore::MockRealtimeVideoSource::drawAnimation):
+        (WebCore::MockRealtimeVideoSource::drawBoxes):
+        (WebCore::MockRealtimeVideoSource::drawText):
+        (WebCore::MockRealtimeVideoSource::generateFrame):
+        (WebCore::MockRealtimeVideoSource::imageBuffer):
+        (WebCore::MockRealtimeVideoSource::setFrameRate): Deleted.
+        (WebCore::MockRealtimeVideoSource::setSize): Deleted.
+        * platform/mock/MockRealtimeVideoSource.h:
+        (WebCore::MockRealtimeVideoSource::size): Deleted.
+
</ins><span class="cx"> 2016-09-02  Brady Eidson  &lt;beidson@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Weak link the GameController.framework on macOS.
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesmediastreamMediaStreamTrackcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp (205347 => 205348)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp        2016-09-02 17:28:00 UTC (rev 205347)
+++ trunk/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp        2016-09-02 17:36:29 UTC (rev 205348)
</span><span class="lines">@@ -35,6 +35,7 @@
</span><span class="cx"> #include &quot;EventNames.h&quot;
</span><span class="cx"> #include &quot;ExceptionCode.h&quot;
</span><span class="cx"> #include &quot;ExceptionCodePlaceholder.h&quot;
</span><ins>+#include &quot;JSOverconstrainedError.h&quot;
</ins><span class="cx"> #include &quot;MediaConstraintsImpl.h&quot;
</span><span class="cx"> #include &quot;MediaSourceSettings.h&quot;
</span><span class="cx"> #include &quot;MediaStream.h&quot;
</span><span class="lines">@@ -41,6 +42,7 @@
</span><span class="cx"> #include &quot;MediaStreamPrivate.h&quot;
</span><span class="cx"> #include &quot;MediaTrackConstraints.h&quot;
</span><span class="cx"> #include &quot;NotImplemented.h&quot;
</span><ins>+#include &quot;OverconstrainedError.h&quot;
</ins><span class="cx"> #include &quot;ScriptExecutionContext.h&quot;
</span><span class="cx"> #include &lt;wtf/NeverDestroyed.h&gt;
</span><span class="cx"> 
</span><span class="lines">@@ -52,9 +54,9 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> MediaStreamTrack::MediaStreamTrack(ScriptExecutionContext&amp; context, MediaStreamTrackPrivate&amp; privateTrack)
</span><del>-    : RefCounted()
-    , ActiveDOMObject(&amp;context)
</del><ins>+    : ActiveDOMObject(&amp;context)
</ins><span class="cx">     , m_private(privateTrack)
</span><ins>+    , m_weakPtrFactory(this)
</ins><span class="cx"> {
</span><span class="cx">     suspendIfNeeded();
</span><span class="cx"> 
</span><span class="lines">@@ -167,18 +169,37 @@
</span><span class="cx">     return m_private-&gt;capabilities();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void MediaStreamTrack::applyConstraints(const Dictionary&amp; constraints)
</del><ins>+void MediaStreamTrack::applyConstraints(Ref&lt;MediaConstraints&gt;&amp;&amp; constraints, ApplyConstraintsPromise&amp;&amp; promise)
</ins><span class="cx"> {
</span><del>-    // FIXME: Implement correctly. https://bugs.webkit.org/show_bug.cgi?id=160579
</del><ins>+    if (!constraints-&gt;isValid()) {
+        promise.reject(TypeError);
+        return;
+    }
</ins><span class="cx"> 
</span><del>-    m_constraints-&gt;initialize(constraints);
-    m_private-&gt;applyConstraints(*m_constraints);
</del><ins>+    m_constraints = WTFMove(constraints);
+    m_promise = WTFMove(promise);
+
+    applyConstraints(*m_constraints);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-void MediaStreamTrack::applyConstraints(const MediaConstraints&amp;)
</del><ins>+void MediaStreamTrack::applyConstraints(const MediaConstraints&amp; constraints)
</ins><span class="cx"> {
</span><del>-    // FIXME: apply the new constraints to the track
-    // https://bugs.webkit.org/show_bug.cgi?id=122428
</del><ins>+    auto weakThis = createWeakPtr();
+    std::function&lt;void(const String&amp;, const String&amp;)&gt; failureHandler = [weakThis](const String&amp; failedConstraint, const String&amp; message) {
+        if (!weakThis || !weakThis-&gt;m_promise)
+            return;
+
+        weakThis-&gt;m_promise-&gt;reject(OverconstrainedError::create(failedConstraint, message).get());
+    };
+
+    std::function&lt;void()&gt; successHandler = [weakThis]() {
+        if (!weakThis || !weakThis-&gt;m_promise)
+            return;
+
+        weakThis-&gt;m_promise-&gt;resolve(nullptr);
+    };
+
+    m_private-&gt;applyConstraints(constraints, successHandler, failureHandler);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void MediaStreamTrack::addObserver(MediaStreamTrack::Observer* observer)
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesmediastreamMediaStreamTrackh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/mediastream/MediaStreamTrack.h (205347 => 205348)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/mediastream/MediaStreamTrack.h        2016-09-02 17:28:00 UTC (rev 205347)
+++ trunk/Source/WebCore/Modules/mediastream/MediaStreamTrack.h        2016-09-02 17:36:29 UTC (rev 205348)
</span><span class="lines">@@ -31,18 +31,20 @@
</span><span class="cx"> 
</span><span class="cx"> #include &quot;ActiveDOMObject.h&quot;
</span><span class="cx"> #include &quot;EventTarget.h&quot;
</span><ins>+#include &quot;JSDOMPromise.h&quot;
</ins><span class="cx"> #include &quot;MediaStreamTrackPrivate.h&quot;
</span><span class="cx"> #include &quot;RealtimeMediaSource.h&quot;
</span><span class="cx"> #include &quot;ScriptWrappable.h&quot;
</span><ins>+#include &lt;wtf/Optional.h&gt;
</ins><span class="cx"> #include &lt;wtf/RefPtr.h&gt;
</span><span class="cx"> #include &lt;wtf/Vector.h&gt;
</span><ins>+#include &lt;wtf/WeakPtr.h&gt;
</ins><span class="cx"> #include &lt;wtf/text/WTFString.h&gt;
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><span class="cx"> class AudioSourceProvider;
</span><del>-class Dictionary;
-class MediaConstraintsImpl;
</del><ins>+class MediaConstraints;
</ins><span class="cx"> class MediaSourceSettings;
</span><span class="cx"> class MediaTrackConstraints;
</span><span class="cx"> 
</span><span class="lines">@@ -79,7 +81,9 @@
</span><span class="cx">     RefPtr&lt;MediaTrackConstraints&gt; getConstraints() const;
</span><span class="cx">     RefPtr&lt;MediaSourceSettings&gt; getSettings() const;
</span><span class="cx">     RefPtr&lt;RealtimeMediaSourceCapabilities&gt; getCapabilities() const;
</span><del>-    void applyConstraints(const Dictionary&amp;);
</del><ins>+
+    using ApplyConstraintsPromise = DOMPromise&lt;std::nullptr_t&gt;;
+    void applyConstraints(Ref&lt;MediaConstraints&gt;&amp;&amp;, ApplyConstraintsPromise&amp;&amp;);
</ins><span class="cx">     void applyConstraints(const MediaConstraints&amp;);
</span><span class="cx"> 
</span><span class="cx">     RealtimeMediaSource&amp; source() const { return m_private-&gt;source(); }
</span><span class="lines">@@ -118,10 +122,14 @@
</span><span class="cx">     void trackSettingsChanged(MediaStreamTrackPrivate&amp;) override;
</span><span class="cx">     void trackEnabledChanged(MediaStreamTrackPrivate&amp;) override;
</span><span class="cx"> 
</span><ins>+    WeakPtr&lt;MediaStreamTrack&gt; createWeakPtr() { return m_weakPtrFactory.createWeakPtr(); }
+
</ins><span class="cx">     Vector&lt;Observer*&gt; m_observers;
</span><span class="cx">     Ref&lt;MediaStreamTrackPrivate&gt; m_private;
</span><span class="cx"> 
</span><del>-    RefPtr&lt;MediaConstraintsImpl&gt; m_constraints;
</del><ins>+    RefPtr&lt;MediaConstraints&gt; m_constraints;
+    Optional&lt;ApplyConstraintsPromise&gt; m_promise;
+    WeakPtrFactory&lt;MediaStreamTrack&gt; m_weakPtrFactory;
</ins><span class="cx"> 
</span><span class="cx">     bool m_ended { false };
</span><span class="cx"> };
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesmediastreamMediaStreamTrackidl"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/mediastream/MediaStreamTrack.idl (205347 => 205348)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/mediastream/MediaStreamTrack.idl        2016-09-02 17:28:00 UTC (rev 205347)
+++ trunk/Source/WebCore/Modules/mediastream/MediaStreamTrack.idl        2016-09-02 17:36:29 UTC (rev 205348)
</span><span class="lines">@@ -47,10 +47,10 @@
</span><span class="cx">     MediaStreamTrack clone();
</span><span class="cx">     [ImplementedAs=stopProducingData] void stop();
</span><span class="cx"> 
</span><del>-    MediaTrackConstraints getConstraints();
</del><ins>+    [Custom] MediaTrackConstraints getConstraints();
</ins><span class="cx">     [Custom] MediaSourceSettings getSettings();
</span><span class="cx">     [Custom] MediaTrackCapabilities getCapabilities();
</span><del>-    void applyConstraints(Dictionary constraints);
</del><ins>+    [Custom] Promise applyConstraints(Dictionary? constraints);
</ins><span class="cx"> 
</span><span class="cx">     attribute EventHandler onoverconstrained;
</span><span class="cx"> };
</span></span></pre></div>
<a id="trunkSourceWebCoreWebCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (205347 => 205348)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2016-09-02 17:28:00 UTC (rev 205347)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2016-09-02 17:36:29 UTC (rev 205348)
</span><span class="lines">@@ -139,6 +139,7 @@
</span><span class="cx">                 07297FA71C1881C5003F0735 /* UserMediaPermissionCheck.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 07297FA51C1881C5003F0735 /* UserMediaPermissionCheck.cpp */; };
</span><span class="cx">                 07297FA81C1881C5003F0735 /* UserMediaPermissionCheck.h in Headers */ = {isa = PBXBuildFile; fileRef = 07297FA61C1881C5003F0735 /* UserMediaPermissionCheck.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 072A70401D6E8F6200DF0AFC /* OverconstrainedErrorEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 072A703E1D6E8F6200DF0AFC /* OverconstrainedErrorEvent.h */; };
</span><ins>+                072A70431D7396B300DF0AFC /* JSMediaDevicesCustom.h in Headers */ = {isa = PBXBuildFile; fileRef = 072A70421D7396B200DF0AFC /* JSMediaDevicesCustom.h */; };
</ins><span class="cx">                 072AE1E5183C0741000A5988 /* PluginReplacement.h in Headers */ = {isa = PBXBuildFile; fileRef = 072AE1DF183C0741000A5988 /* PluginReplacement.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 072AE1E6183C0741000A5988 /* QuickTimePluginReplacement.mm in Sources */ = {isa = PBXBuildFile; fileRef = 072AE1E0183C0741000A5988 /* QuickTimePluginReplacement.mm */; };
</span><span class="cx">                 072AE1E8183C0741000A5988 /* QuickTimePluginReplacement.h in Headers */ = {isa = PBXBuildFile; fileRef = 072AE1E2183C0741000A5988 /* QuickTimePluginReplacement.h */; };
</span><span class="lines">@@ -6943,6 +6944,7 @@
</span><span class="cx">                 07297FA61C1881C5003F0735 /* UserMediaPermissionCheck.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UserMediaPermissionCheck.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><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><ins>+                072A70421D7396B200DF0AFC /* JSMediaDevicesCustom.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSMediaDevicesCustom.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 072AE1DF183C0741000A5988 /* PluginReplacement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PluginReplacement.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 072AE1E0183C0741000A5988 /* QuickTimePluginReplacement.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = QuickTimePluginReplacement.mm; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 072AE1E1183C0741000A5988 /* QuickTimePluginReplacement.css */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.css; path = QuickTimePluginReplacement.css; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -21096,6 +21098,7 @@
</span><span class="cx">                                 7A74ECBC101839DA00BF939E /* JSInspectorFrontendHostCustom.cpp */,
</span><span class="cx">                                 BCE1C43F0D9830F4003B02F2 /* JSLocationCustom.cpp */,
</span><span class="cx">                                 1B88DD121D5AD3B200E3B7A4 /* JSMediaDevicesCustom.cpp */,
</span><ins>+                                072A70421D7396B200DF0AFC /* JSMediaDevicesCustom.h */,
</ins><span class="cx">                                 AD726FE716D9F204003A4E6D /* JSMediaListCustom.h */,
</span><span class="cx">                                 07C59B6D17F794F6000FBCBB /* JSMediaStreamTrackCustom.cpp */,
</span><span class="cx">                                 07C1C0E61BFB90A700BD2256 /* JSMediaTrackSupportedConstraintsCustom.cpp */,
</span><span class="lines">@@ -26281,6 +26284,7 @@
</span><span class="cx">                                 93309EA3099EB78C0056E581 /* SharedTimer.h in Headers */,
</span><span class="cx">                                 E48944A3180B57D800F165D8 /* SimpleLineLayout.h in Headers */,
</span><span class="cx">                                 585D6E041A1A792E00FA4F12 /* SimpleLineLayoutFlowContents.h in Headers */,
</span><ins>+                                072A70431D7396B300DF0AFC /* JSMediaDevicesCustom.h in Headers */,
</ins><span class="cx">                                 E4E9B11D1814569C003ACCDF /* SimpleLineLayoutFunctions.h in Headers */,
</span><span class="cx">                                 E4E9B1191810916F003ACCDF /* SimpleLineLayoutResolver.h in Headers */,
</span><span class="cx">                                 582CB0531A78A14B00AFFCC4 /* SimpleLineLayoutTextFragmentIterator.h in Headers */,
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsjsJSMediaDevicesCustomcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/js/JSMediaDevicesCustom.cpp (205347 => 205348)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/js/JSMediaDevicesCustom.cpp        2016-09-02 17:28:00 UTC (rev 205347)
+++ trunk/Source/WebCore/bindings/js/JSMediaDevicesCustom.cpp        2016-09-02 17:36:29 UTC (rev 205348)
</span><span class="lines">@@ -24,7 +24,7 @@
</span><span class="cx">  */
</span><span class="cx"> 
</span><span class="cx"> #include &quot;config.h&quot;
</span><del>-#include &quot;JSMediaDevices.h&quot;
</del><ins>+#include &quot;JSMediaDevicesCustom.h&quot;
</ins><span class="cx"> 
</span><span class="cx"> #if ENABLE(MEDIA_STREAM)
</span><span class="cx"> 
</span><span class="lines">@@ -31,8 +31,8 @@
</span><span class="cx"> #include &quot;ArrayValue.h&quot;
</span><span class="cx"> #include &quot;Dictionary.h&quot;
</span><span class="cx"> #include &quot;ExceptionCode.h&quot;
</span><ins>+#include &quot;JSMediaDevices.h&quot;
</ins><span class="cx"> #include &quot;Logging.h&quot;
</span><del>-#include &quot;MediaConstraints.h&quot;
</del><span class="cx"> #include &quot;MediaConstraintsImpl.h&quot;
</span><span class="cx"> #include &quot;RealtimeMediaSourceCenter.h&quot;
</span><span class="cx"> #include &quot;RealtimeMediaSourceSupportedConstraints.h&quot;
</span><span class="lines">@@ -60,7 +60,7 @@
</span><span class="cx"> 
</span><span class="cx"> static RefPtr&lt;StringConstraint&gt; createStringConstraint(const Dictionary&amp; mediaTrackConstraintSet, const String&amp; name, MediaConstraintType type, ConstraintSetType constraintSetType)
</span><span class="cx"> {
</span><del>-    auto constraint = StringConstraint::create(type);
</del><ins>+    auto constraint = StringConstraint::create(name, type);
</ins><span class="cx"> 
</span><span class="cx">     // Dictionary constraint value.
</span><span class="cx">     Dictionary dictionaryValue;
</span><span class="lines">@@ -122,7 +122,7 @@
</span><span class="cx"> 
</span><span class="cx"> static RefPtr&lt;BooleanConstraint&gt; createBooleanConstraint(const Dictionary&amp; mediaTrackConstraintSet, const String&amp; name, MediaConstraintType type, ConstraintSetType constraintSetType)
</span><span class="cx"> {
</span><del>-    auto constraint = BooleanConstraint::create(type);
</del><ins>+    auto constraint = BooleanConstraint::create(name, type);
</ins><span class="cx"> 
</span><span class="cx">     // Dictionary constraint value.
</span><span class="cx">     Dictionary dictionaryValue;
</span><span class="lines">@@ -161,7 +161,7 @@
</span><span class="cx"> 
</span><span class="cx"> static RefPtr&lt;DoubleConstraint&gt; createDoubleConstraint(const Dictionary&amp; mediaTrackConstraintSet, const String&amp; name, MediaConstraintType type, ConstraintSetType constraintSetType)
</span><span class="cx"> {
</span><del>-    auto constraint = DoubleConstraint::create(type);
</del><ins>+    auto constraint = DoubleConstraint::create(name, type);
</ins><span class="cx"> 
</span><span class="cx">     // Dictionary constraint value.
</span><span class="cx">     Dictionary dictionaryValue;
</span><span class="lines">@@ -208,7 +208,7 @@
</span><span class="cx"> 
</span><span class="cx"> static RefPtr&lt;IntConstraint&gt; createIntConstraint(const Dictionary&amp; mediaTrackConstraintSet, const String&amp; name, MediaConstraintType type, ConstraintSetType constraintSetType)
</span><span class="cx"> {
</span><del>-    auto constraint = IntConstraint::create(type);
</del><ins>+    auto constraint = IntConstraint::create(name, type);
</ins><span class="cx"> 
</span><span class="cx">     // Dictionary constraint value.
</span><span class="cx">     Dictionary dictionaryValue;
</span><span class="lines">@@ -253,61 +253,45 @@
</span><span class="cx">     return nullptr;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static void parseMediaTrackConstraintSetForKey(const Dictionary&amp; mediaTrackConstraintSet, const String&amp; name, MediaTrackConstraintSetMap&amp; map, ConstraintSetType constraintSetType, RealtimeMediaSource::Type sourceType)
</del><ins>+static void parseMediaTrackConstraintSetForKey(const Dictionary&amp; mediaTrackConstraintSet, const String&amp; name, MediaTrackConstraintSetMap&amp; map, ConstraintSetType constraintSetType)
</ins><span class="cx"> {
</span><span class="cx">     MediaConstraintType constraintType = RealtimeMediaSourceSupportedConstraints::constraintFromName(name);
</span><span class="cx"> 
</span><span class="cx">     RefPtr&lt;MediaConstraint&gt; mediaConstraint;
</span><del>-    if (sourceType == RealtimeMediaSource::Audio) {
-        switch (constraintType) {
-        case MediaConstraintType::SampleRate:
-        case MediaConstraintType::SampleSize:
-            mediaConstraint = createIntConstraint(mediaTrackConstraintSet, name, constraintType, constraintSetType);
-            break;
-        case MediaConstraintType::Volume:
-            mediaConstraint = createDoubleConstraint(mediaTrackConstraintSet, name, constraintType, constraintSetType);
-            break;
-        case MediaConstraintType::EchoCancellation:
-            mediaConstraint = createBooleanConstraint(mediaTrackConstraintSet, name, constraintType, constraintSetType);
-            break;
-        case MediaConstraintType::DeviceId:
-        case MediaConstraintType::GroupId:
-            mediaConstraint = createStringConstraint(mediaTrackConstraintSet, name, constraintType, constraintSetType);
-            break;
-        default:
-            LOG(Media, &quot;parseMediaTrackConstraintSetForKey() - ignoring unsupported constraint '%s' for audio.&quot;, name.utf8().data());
-            mediaConstraint = nullptr;
-            break;
-        }
-    } else if (sourceType == RealtimeMediaSource::Video) {
-        switch (constraintType) {
-        case MediaConstraintType::Width:
-        case MediaConstraintType::Height:
-            mediaConstraint = createIntConstraint(mediaTrackConstraintSet, name, constraintType, constraintSetType);
-            break;
-        case MediaConstraintType::AspectRatio:
-        case MediaConstraintType::FrameRate:
-            mediaConstraint = createDoubleConstraint(mediaTrackConstraintSet, name, constraintType, constraintSetType);
-            break;
-        case MediaConstraintType::FacingMode:
-        case MediaConstraintType::DeviceId:
-        case MediaConstraintType::GroupId:
-            mediaConstraint = createStringConstraint(mediaTrackConstraintSet, name, constraintType, constraintSetType);
-            break;
-        default:
-            LOG(Media, &quot;parseMediaTrackConstraintSetForKey() - ignoring unsupported constraint '%s' for video.&quot;, name.utf8().data());
-            mediaConstraint = nullptr;
-            break;
-        }
-    }
</del><ins>+    switch (constraintType) {
+    case MediaConstraintType::Width:
+    case MediaConstraintType::Height:
+    case MediaConstraintType::SampleRate:
+    case MediaConstraintType::SampleSize:
+        mediaConstraint = createIntConstraint(mediaTrackConstraintSet, name, constraintType, constraintSetType);
+        break;
</ins><span class="cx"> 
</span><del>-    if (!mediaConstraint)
-        return;
</del><ins>+    case MediaConstraintType::AspectRatio:
+    case MediaConstraintType::FrameRate:
+    case MediaConstraintType::Volume:
+        mediaConstraint = createDoubleConstraint(mediaTrackConstraintSet, name, constraintType, constraintSetType);
+        break;
</ins><span class="cx"> 
</span><ins>+    case MediaConstraintType::EchoCancellation:
+        mediaConstraint = createBooleanConstraint(mediaTrackConstraintSet, name, constraintType, constraintSetType);
+        break;
+
+    case MediaConstraintType::FacingMode:
+    case MediaConstraintType::DeviceId:
+    case MediaConstraintType::GroupId:
+        mediaConstraint = createStringConstraint(mediaTrackConstraintSet, name, constraintType, constraintSetType);
+        break;
+
+    case MediaConstraintType::Unknown:
+        LOG(Media, &quot;parseMediaTrackConstraintSetForKey() - found unsupported constraint '%s'.&quot;, name.utf8().data());
+        mediaConstraint = UnknownConstraint::create(name, constraintType);
+        break;
+    }
+    
</ins><span class="cx">     map.add(name, WTFMove(mediaConstraint));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static void parseAdvancedConstraints(const Dictionary&amp; mediaTrackConstraints, Vector&lt;MediaTrackConstraintSetMap&gt;&amp; advancedConstraints, RealtimeMediaSource::Type sourceType)
</del><ins>+static void parseAdvancedConstraints(const Dictionary&amp; mediaTrackConstraints, Vector&lt;MediaTrackConstraintSetMap&gt;&amp; advancedConstraints)
</ins><span class="cx"> {
</span><span class="cx">     ArrayValue sequenceOfMediaTrackConstraintSets;
</span><span class="cx">     if (!mediaTrackConstraints.get(&quot;advanced&quot;, sequenceOfMediaTrackConstraintSets) || sequenceOfMediaTrackConstraintSets.isUndefinedOrNull()) {
</span><span class="lines">@@ -333,7 +317,7 @@
</span><span class="cx">         Vector&lt;String&gt; localKeys;
</span><span class="cx">         mediaTrackConstraintSet.getOwnPropertyNames(localKeys);
</span><span class="cx">         for (auto&amp; localKey : localKeys)
</span><del>-            parseMediaTrackConstraintSetForKey(mediaTrackConstraintSet, localKey, map, ConstraintSetType::Advanced, sourceType);
</del><ins>+            parseMediaTrackConstraintSetForKey(mediaTrackConstraintSet, localKey, map, ConstraintSetType::Advanced);
</ins><span class="cx"> 
</span><span class="cx">         if (!map.isEmpty())
</span><span class="cx">             advancedConstraints.append(WTFMove(map));
</span><span class="lines">@@ -340,7 +324,7 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static void parseConstraints(const Dictionary&amp; mediaTrackConstraints, MediaTrackConstraintSetMap&amp; mandatoryConstraints, Vector&lt;MediaTrackConstraintSetMap&gt;&amp; advancedConstraints, RealtimeMediaSource::Type sourceType)
</del><ins>+void parseMediaConstraintsDictionary(const Dictionary&amp; mediaTrackConstraints, MediaTrackConstraintSetMap&amp; mandatoryConstraints, Vector&lt;MediaTrackConstraintSetMap&gt;&amp; advancedConstraints)
</ins><span class="cx"> {
</span><span class="cx">     if (mediaTrackConstraints.isUndefinedOrNull())
</span><span class="cx">         return;
</span><span class="lines">@@ -350,9 +334,9 @@
</span><span class="cx"> 
</span><span class="cx">     for (auto&amp; key : keys) {
</span><span class="cx">         if (key == &quot;advanced&quot;)
</span><del>-            parseAdvancedConstraints(mediaTrackConstraints, advancedConstraints, sourceType);
</del><ins>+            parseAdvancedConstraints(mediaTrackConstraints, advancedConstraints);
</ins><span class="cx">         else
</span><del>-            parseMediaTrackConstraintSetForKey(mediaTrackConstraints, key, mandatoryConstraints, ConstraintSetType::Mandatory, sourceType);
</del><ins>+            parseMediaTrackConstraintSetForKey(mediaTrackConstraints, key, mandatoryConstraints, ConstraintSetType::Mandatory);
</ins><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -372,7 +356,7 @@
</span><span class="cx"> 
</span><span class="cx">     Dictionary audioConstraintsDictionary;
</span><span class="cx">     if (constraintsDictionary.get(&quot;audio&quot;, audioConstraintsDictionary) &amp;&amp; !audioConstraintsDictionary.isUndefinedOrNull()) {
</span><del>-        parseConstraints(audioConstraintsDictionary, mandatoryAudioConstraints, advancedAudioConstraints, RealtimeMediaSource::Audio);
</del><ins>+        parseMediaConstraintsDictionary(audioConstraintsDictionary, mandatoryAudioConstraints, advancedAudioConstraints);
</ins><span class="cx">         areAudioConstraintsValid = true;
</span><span class="cx">     } else
</span><span class="cx">         constraintsDictionary.get(&quot;audio&quot;, areAudioConstraintsValid);
</span><span class="lines">@@ -383,7 +367,7 @@
</span><span class="cx"> 
</span><span class="cx">     Dictionary videoConstraintsDictionary;
</span><span class="cx">     if (constraintsDictionary.get(&quot;video&quot;, videoConstraintsDictionary) &amp;&amp; !videoConstraintsDictionary.isUndefinedOrNull()) {
</span><del>-        parseConstraints(videoConstraintsDictionary, mandatoryVideoConstraints, advancedVideoConstraints, RealtimeMediaSource::Video);
</del><ins>+        parseMediaConstraintsDictionary(videoConstraintsDictionary, mandatoryVideoConstraints, advancedVideoConstraints);
</ins><span class="cx">         areVideoConstraintsValid = true;
</span><span class="cx">     } else
</span><span class="cx">         constraintsDictionary.get(&quot;video&quot;, areVideoConstraintsValid);
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsjsJSMediaDevicesCustomh"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/bindings/js/JSMediaDevicesCustom.h (0 => 205348)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/js/JSMediaDevicesCustom.h                                (rev 0)
+++ trunk/Source/WebCore/bindings/js/JSMediaDevicesCustom.h        2016-09-02 17:36:29 UTC (rev 205348)
</span><span class="lines">@@ -0,0 +1,41 @@
</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;MediaConstraints.h&quot;
+#include &lt;wtf/Vector.h&gt;
+
+namespace WebCore {
+
+class Dictionary;
+
+void parseMediaConstraintsDictionary(const Dictionary&amp;, MediaTrackConstraintSetMap&amp;, Vector&lt;MediaTrackConstraintSetMap&gt;&amp;);
+
+}
+
+#endif
</ins></span></pre></div>
<a id="trunkSourceWebCorebindingsjsJSMediaStreamTrackCustomcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/js/JSMediaStreamTrackCustom.cpp (205347 => 205348)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/js/JSMediaStreamTrackCustom.cpp        2016-09-02 17:28:00 UTC (rev 205347)
+++ trunk/Source/WebCore/bindings/js/JSMediaStreamTrackCustom.cpp        2016-09-02 17:36:29 UTC (rev 205348)
</span><span class="lines">@@ -28,10 +28,14 @@
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(MEDIA_STREAM)
</span><span class="cx"> 
</span><ins>+#include &quot;Dictionary.h&quot;
</ins><span class="cx"> #include &quot;ExceptionCode.h&quot;
</span><span class="cx"> #include &quot;JSDOMBinding.h&quot;
</span><ins>+#include &quot;JSMediaDevicesCustom.h&quot;
+#include &quot;MediaConstraintsImpl.h&quot;
</ins><span class="cx"> #include &quot;MediaSourceSettings.h&quot;
</span><span class="cx"> #include &quot;MediaStreamTrack.h&quot;
</span><ins>+#include &quot;WebCoreJSClientData.h&quot;
</ins><span class="cx"> #include &lt;runtime/JSObject.h&gt;
</span><span class="cx"> #include &lt;runtime/ObjectConstructor.h&gt;
</span><span class="cx"> 
</span><span class="lines">@@ -57,7 +61,7 @@
</span><span class="cx">         object-&gt;putDirect(state.vm(), Identifier::fromString(&amp;state, &quot;width&quot;), jsNumber(settings-&gt;width()), DontDelete | ReadOnly);
</span><span class="cx">     if (settings-&gt;supportsHeight())
</span><span class="cx">         object-&gt;putDirect(state.vm(), Identifier::fromString(&amp;state, &quot;height&quot;), jsNumber(settings-&gt;height()), DontDelete | ReadOnly);
</span><del>-    if (settings-&gt;supportsAspectRatio())
</del><ins>+    if (settings-&gt;supportsAspectRatio() &amp;&amp; settings-&gt;aspectRatio())
</ins><span class="cx">         object-&gt;putDirect(state.vm(), Identifier::fromString(&amp;state, &quot;aspectRatio&quot;), jsDoubleNumber(settings-&gt;aspectRatio()), DontDelete | ReadOnly);
</span><span class="cx">     if (settings-&gt;supportsFrameRate())
</span><span class="cx">         object-&gt;putDirect(state.vm(), Identifier::fromString(&amp;state, &quot;frameRate&quot;), jsDoubleNumber(settings-&gt;frameRate()), DontDelete | ReadOnly);
</span><span class="lines">@@ -90,8 +94,8 @@
</span><span class="cx">             object-&gt;putDirect(state.vm(), Identifier::fromString(&amp;state, &quot;min&quot;), jsNumber(min.asDouble));
</span><span class="cx">             object-&gt;putDirect(state.vm(), Identifier::fromString(&amp;state, &quot;max&quot;), jsNumber(max.asDouble));
</span><span class="cx">         } else {
</span><del>-            object-&gt;putDirect(state.vm(), Identifier::fromString(&amp;state, &quot;min&quot;), jsNumber(min.asULong));
-            object-&gt;putDirect(state.vm(), Identifier::fromString(&amp;state, &quot;max&quot;), jsNumber(max.asULong));
</del><ins>+            object-&gt;putDirect(state.vm(), Identifier::fromString(&amp;state, &quot;min&quot;), jsNumber(min.asInt));
+            object-&gt;putDirect(state.vm(), Identifier::fromString(&amp;state, &quot;max&quot;), jsNumber(max.asInt));
</ins><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         return object;
</span><span class="lines">@@ -100,7 +104,7 @@
</span><span class="cx">     if (value.type() == CapabilityValueOrRange::Double)
</span><span class="cx">         return jsNumber(value.value().asDouble);
</span><span class="cx"> 
</span><del>-    return jsNumber(value.value().asULong);
</del><ins>+    return jsNumber(value.value().asInt);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> JSC::JSValue JSMediaStreamTrack::getCapabilities(ExecState&amp; state)
</span><span class="lines">@@ -162,6 +166,38 @@
</span><span class="cx">     return object;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+JSValue JSMediaStreamTrack::applyConstraints(ExecState&amp; state)
+{
+    MediaTrackConstraintSetMap mandatoryConstraints;
+    Vector&lt;MediaTrackConstraintSetMap&gt; advancedConstraints;
+    bool valid = false;
+
+    if (state.argumentCount() &gt;= 1) {
+        JSValue argument = state.uncheckedArgument(0);
+
+        JSVMClientData&amp; clientData = *static_cast&lt;JSVMClientData*&gt;(state.vm().clientData);
+        putDirect(state.vm(), clientData.builtinNames().mediaStreamTrackConstraintsPrivateName(), argument, DontEnum);
+
+        auto constraintsDictionary = Dictionary(&amp;state, argument);
+        if (!constraintsDictionary.isUndefinedOrNull())
+            parseMediaConstraintsDictionary(constraintsDictionary, mandatoryConstraints, advancedConstraints);
+        valid = !advancedConstraints.isEmpty() || !mandatoryConstraints.isEmpty();
+    }
+
+    JSC::JSPromiseDeferred* promiseDeferred = JSC::JSPromiseDeferred::create(&amp;state, globalObject());
+    auto constraints = MediaConstraintsImpl::create(WTFMove(mandatoryConstraints), WTFMove(advancedConstraints), valid);
+    wrapped().applyConstraints(WTFMove(constraints), DeferredWrapper::create(&amp;state, globalObject(), promiseDeferred));
+
+    return promiseDeferred-&gt;promise();
+}
+
+JSValue JSMediaStreamTrack::getConstraints(ExecState&amp; state)
+{
+    JSVMClientData&amp; clientData = *static_cast&lt;JSVMClientData*&gt;(state.vm().clientData);
+    JSValue result = getDirect(state.vm(), clientData.builtinNames().mediaStreamTrackConstraintsPrivateName());
+    return !result.isEmpty() ? result : jsUndefined();
+}
+
</ins><span class="cx"> } // namespace WebCore
</span><span class="cx"> 
</span><span class="cx"> #endif
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsjsWebCoreBuiltinNamesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/js/WebCoreBuiltinNames.h (205347 => 205348)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/js/WebCoreBuiltinNames.h        2016-09-02 17:28:00 UTC (rev 205347)
+++ trunk/Source/WebCore/bindings/js/WebCoreBuiltinNames.h        2016-09-02 17:36:29 UTC (rev 205348)
</span><span class="lines">@@ -58,6 +58,7 @@
</span><span class="cx">     macro(localStreams) \
</span><span class="cx">     macro(makeThisTypeError) \
</span><span class="cx">     macro(makeGetterTypeError) \
</span><ins>+    macro(mediaStreamTrackConstraints) \
</ins><span class="cx">     macro(operations) \
</span><span class="cx">     macro(ownerReadableStream) \
</span><span class="cx">     macro(privateGetStats) \
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlHTMLMediaElementcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/HTMLMediaElement.cpp (205347 => 205348)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/HTMLMediaElement.cpp        2016-09-02 17:28:00 UTC (rev 205347)
+++ trunk/Source/WebCore/html/HTMLMediaElement.cpp        2016-09-02 17:36:29 UTC (rev 205348)
</span><span class="lines">@@ -1001,7 +1001,8 @@
</span><span class="cx">     // https://bugs.webkit.org/show_bug.cgi?id=124896
</span><span class="cx"> 
</span><span class="cx">     m_mediaStreamSrcObject = mediaStream;
</span><del>-    setSrc(DOMURL::createPublicURL(context, mediaStream));
</del><ins>+    if (mediaStream)
+        setSrc(DOMURL::createPublicURL(context, mediaStream));
</ins><span class="cx"> }
</span><span class="cx"> #endif
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsavfoundationobjcMediaPlayerPrivateMediaStreamAVFObjCmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.mm (205347 => 205348)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.mm        2016-09-02 17:28:00 UTC (rev 205347)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.mm        2016-09-02 17:36:29 UTC (rev 205348)
</span><span class="lines">@@ -312,6 +312,7 @@
</span><span class="cx">     m_playing = true;
</span><span class="cx">     m_haveEverPlayed = true;
</span><span class="cx">     scheduleDeferredTask([this] {
</span><ins>+        updateDisplayMode();
</ins><span class="cx">         updateReadyState();
</span><span class="cx">     });
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformmediastreamMediaConstraintscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/mediastream/MediaConstraints.cpp (205347 => 205348)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/mediastream/MediaConstraints.cpp        2016-09-02 17:28:00 UTC (rev 205347)
+++ trunk/Source/WebCore/platform/mediastream/MediaConstraints.cpp        2016-09-02 17:36:29 UTC (rev 205348)
</span><span class="lines">@@ -46,19 +46,19 @@
</span><span class="cx">     case MediaConstraintType::Height:
</span><span class="cx">     case MediaConstraintType::SampleRate:
</span><span class="cx">     case MediaConstraintType::SampleSize:
</span><del>-        return IntConstraint::create(constraintType);
</del><ins>+        return IntConstraint::create(name, constraintType);
</ins><span class="cx">     case MediaConstraintType::AspectRatio:
</span><span class="cx">     case MediaConstraintType::FrameRate:
</span><span class="cx">     case MediaConstraintType::Volume:
</span><del>-        return DoubleConstraint::create(constraintType);
</del><ins>+        return DoubleConstraint::create(name, constraintType);
</ins><span class="cx">     case MediaConstraintType::EchoCancellation:
</span><del>-        return BooleanConstraint::create(constraintType);
</del><ins>+        return BooleanConstraint::create(name, constraintType);
</ins><span class="cx">     case MediaConstraintType::FacingMode:
</span><span class="cx">     case MediaConstraintType::DeviceId:
</span><span class="cx">     case MediaConstraintType::GroupId:
</span><del>-        return StringConstraint::create(constraintType);
</del><ins>+        return StringConstraint::create(name, constraintType);
</ins><span class="cx">     case MediaConstraintType::Unknown:
</span><del>-        return nullptr;
</del><ins>+        return UnknownConstraint::create(name, constraintType);
</ins><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -121,6 +121,21 @@
</span><span class="cx">     return true;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+const String&amp; StringConstraint::find(std::function&lt;bool(ConstraintType, const String&amp;)&gt; filter) const
+{
+    for (auto&amp; constraint : m_exact) {
+        if (filter(ConstraintType::ExactConstraint, constraint))
+            return constraint;
+    }
+
+    for (auto&amp; constraint : m_ideal) {
+        if (filter(ConstraintType::IdealConstraint, constraint))
+            return constraint;
+    }
+    
+    return emptyString();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><ins>+}
+
</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 (205347 => 205348)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/mediastream/MediaConstraints.h        2016-09-02 17:28:00 UTC (rev 205347)
+++ trunk/Source/WebCore/platform/mediastream/MediaConstraints.h        2016-09-02 17:36:29 UTC (rev 205348)
</span><span class="lines">@@ -45,6 +45,8 @@
</span><span class="cx"> public:
</span><span class="cx">     static RefPtr&lt;MediaConstraint&gt; create(const String&amp; name);
</span><span class="cx"> 
</span><ins>+    enum class ConstraintType { ExactConstraint, IdealConstraint, MinConstraint, MaxConstraint };
+
</ins><span class="cx">     virtual ~MediaConstraint() { };
</span><span class="cx">     virtual bool isEmpty() const = 0;
</span><span class="cx">     virtual bool isMandatory() const = 0;
</span><span class="lines">@@ -53,11 +55,15 @@
</span><span class="cx">     virtual bool getMax(int&amp;) const { ASSERT_NOT_REACHED(); return false; }
</span><span class="cx">     virtual bool getExact(int&amp;) const { ASSERT_NOT_REACHED(); return false; }
</span><span class="cx">     virtual bool getIdeal(int&amp;) const { ASSERT_NOT_REACHED(); return false; }
</span><ins>+    virtual bool validForRange(int, int) const { ASSERT_NOT_REACHED(); return false; }
+    virtual int find(std::function&lt;bool(ConstraintType, int)&gt;) const { ASSERT_NOT_REACHED(); return 0; }
</ins><span class="cx"> 
</span><span class="cx">     virtual bool getMin(double&amp;) const { ASSERT_NOT_REACHED(); return false; }
</span><span class="cx">     virtual bool getMax(double&amp;) const { ASSERT_NOT_REACHED(); return false; }
</span><span class="cx">     virtual bool getExact(double&amp;) const { ASSERT_NOT_REACHED(); return false; }
</span><span class="cx">     virtual bool getIdeal(double&amp;) const { ASSERT_NOT_REACHED(); return false; }
</span><ins>+    virtual bool validForRange(double, double) const { ASSERT_NOT_REACHED(); return false; }
+    virtual double find(std::function&lt;bool(ConstraintType, double)&gt;) const { ASSERT_NOT_REACHED(); return 0; }
</ins><span class="cx"> 
</span><span class="cx">     virtual bool getMin(bool&amp;) const { ASSERT_NOT_REACHED(); return false; }
</span><span class="cx">     virtual bool getMax(bool&amp;) const { ASSERT_NOT_REACHED(); return false; }
</span><span class="lines">@@ -68,16 +74,20 @@
</span><span class="cx">     virtual bool getMax(Vector&lt;String&gt;&amp;) const { ASSERT_NOT_REACHED(); return false; }
</span><span class="cx">     virtual bool getExact(Vector&lt;String&gt;&amp;) const { ASSERT_NOT_REACHED(); return false; }
</span><span class="cx">     virtual bool getIdeal(Vector&lt;String&gt;&amp;) const { ASSERT_NOT_REACHED(); return false; }
</span><ins>+    virtual const String&amp; find(std::function&lt;bool(ConstraintType, const String&amp;)&gt;) const { ASSERT_NOT_REACHED(); return emptyString(); }
</ins><span class="cx"> 
</span><span class="cx">     MediaConstraintType type() const { return m_type; }
</span><ins>+    const String&amp; name() const { return m_name; }
</ins><span class="cx"> 
</span><span class="cx"> protected:
</span><del>-    explicit MediaConstraint(MediaConstraintType type)
-        : m_type(type)
</del><ins>+    explicit MediaConstraint(const String&amp; name, MediaConstraintType type)
+        : m_name(name)
+        , m_type(type)
</ins><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx"> private:
</span><ins>+    String m_name;
</ins><span class="cx">     MediaConstraintType m_type;
</span><span class="cx"> };
</span><span class="cx"> 
</span><span class="lines">@@ -124,9 +134,42 @@
</span><span class="cx">         return true;
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    bool validForRange(ValueType rangeMin, ValueType rangeMax) const final {
+        if (isEmpty())
+            return false;
+
+        if (m_exact &amp;&amp; (m_exact.value() &lt; rangeMin || m_exact.value() &gt; rangeMax))
+            return false;
+
+        if (m_min &amp;&amp; m_min.value() &gt; rangeMax)
+            return false;
+
+        if (m_max &amp;&amp; m_max.value() &lt; rangeMin)
+            return false;
+
+        return true;
+    }
+
+    ValueType find(std::function&lt;bool(ConstraintType, ValueType)&gt; function) const final {
+        if (m_min &amp;&amp; function(ConstraintType::MinConstraint, m_min.value()))
+            return m_min.value();
+
+        if (m_max &amp;&amp; function(ConstraintType::MaxConstraint, m_max.value()))
+            return m_max.value();
+
+        if (m_exact &amp;&amp; function(ConstraintType::ExactConstraint, m_exact.value()))
+            return m_exact.value();
+
+        if (m_ideal &amp;&amp; function(ConstraintType::IdealConstraint, m_ideal.value()))
+            return m_ideal.value();
+
+        return 0;
+    }
+    
+
</ins><span class="cx"> protected:
</span><del>-    explicit NumericConstraint(MediaConstraintType type)
-        : MediaConstraint(type)
</del><ins>+    explicit NumericConstraint(const String&amp; name, MediaConstraintType type)
+        : MediaConstraint(name, type)
</ins><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -139,11 +182,11 @@
</span><span class="cx"> 
</span><span class="cx"> class IntConstraint final : public NumericConstraint&lt;int&gt; {
</span><span class="cx"> public:
</span><del>-    static Ref&lt;IntConstraint&gt; create(MediaConstraintType type) { return adoptRef(*new IntConstraint(type)); }
</del><ins>+    static Ref&lt;IntConstraint&gt; create(const String&amp; name, MediaConstraintType type) { return adoptRef(*new IntConstraint(name, type)); }
</ins><span class="cx"> 
</span><span class="cx"> private:
</span><del>-    explicit IntConstraint(MediaConstraintType type)
-        : NumericConstraint&lt;int&gt;(type)
</del><ins>+    explicit IntConstraint(const String&amp; name, MediaConstraintType type)
+        : NumericConstraint&lt;int&gt;(name, type)
</ins><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx"> };
</span><span class="lines">@@ -150,11 +193,11 @@
</span><span class="cx"> 
</span><span class="cx"> class DoubleConstraint final : public NumericConstraint&lt;double&gt; {
</span><span class="cx"> public:
</span><del>-    static Ref&lt;DoubleConstraint&gt; create(MediaConstraintType type) { return adoptRef(*new DoubleConstraint(type)); }
</del><ins>+    static Ref&lt;DoubleConstraint&gt; create(const String&amp; name, MediaConstraintType type) { return adoptRef(*new DoubleConstraint(name, type)); }
</ins><span class="cx"> 
</span><span class="cx"> private:
</span><del>-    explicit DoubleConstraint(MediaConstraintType type)
-        : NumericConstraint&lt;double&gt;(type)
</del><ins>+    explicit DoubleConstraint(const String&amp; name, MediaConstraintType type)
+        : NumericConstraint&lt;double&gt;(name, type)
</ins><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx"> };
</span><span class="lines">@@ -161,7 +204,7 @@
</span><span class="cx"> 
</span><span class="cx"> class BooleanConstraint final : public MediaConstraint {
</span><span class="cx"> public:
</span><del>-    static Ref&lt;BooleanConstraint&gt; create(MediaConstraintType type) { return adoptRef(*new BooleanConstraint(type)); }
</del><ins>+    static Ref&lt;BooleanConstraint&gt; create(const String&amp; name, MediaConstraintType type) { return adoptRef(*new BooleanConstraint(name, type)); }
</ins><span class="cx"> 
</span><span class="cx">     void setExact(bool value) { m_exact = value; }
</span><span class="cx">     void setIdeal(bool value) { m_ideal = value; }
</span><span class="lines">@@ -173,18 +216,18 @@
</span><span class="cx">     bool isMandatory() const final { return bool(m_exact); }
</span><span class="cx"> 
</span><span class="cx"> private:
</span><del>-    explicit BooleanConstraint(MediaConstraintType type)
-        : MediaConstraint(type)
</del><ins>+    explicit BooleanConstraint(const String&amp; name, MediaConstraintType type)
+        : MediaConstraint(name, type)
</ins><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    Optional&lt;bool&gt; m_exact { false };
-    Optional&lt;bool&gt; m_ideal { false };
</del><ins>+    Optional&lt;bool&gt; m_exact;
+    Optional&lt;bool&gt; m_ideal;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> class StringConstraint final : public MediaConstraint {
</span><span class="cx"> public:
</span><del>-    static Ref&lt;StringConstraint&gt; create(MediaConstraintType type) { return adoptRef(*new StringConstraint(type)); }
</del><ins>+    static Ref&lt;StringConstraint&gt; create(const String&amp; name, MediaConstraintType type) { return adoptRef(*new StringConstraint(name, type)); }
</ins><span class="cx"> 
</span><span class="cx">     void setExact(const String&amp;);
</span><span class="cx">     void appendExact(const String&amp;);
</span><span class="lines">@@ -197,9 +240,11 @@
</span><span class="cx">     bool isEmpty() const final { return m_exact.isEmpty() &amp;&amp; m_ideal.isEmpty(); }
</span><span class="cx">     bool isMandatory() const final { return !m_exact.isEmpty(); }
</span><span class="cx"> 
</span><ins>+    const String&amp; find(std::function&lt;bool(ConstraintType, const String&amp;)&gt;) const override;
+
</ins><span class="cx"> private:
</span><del>-    explicit StringConstraint(MediaConstraintType type)
-        : MediaConstraint(type)
</del><ins>+    explicit StringConstraint(const String&amp; name, MediaConstraintType type)
+        : MediaConstraint(name, type)
</ins><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -207,6 +252,20 @@
</span><span class="cx">     Vector&lt;String&gt; m_ideal;
</span><span class="cx"> };
</span><span class="cx"> 
</span><ins>+class UnknownConstraint final : public MediaConstraint {
+public:
+    static Ref&lt;UnknownConstraint&gt; create(const String&amp; name, MediaConstraintType type) { return adoptRef(*new UnknownConstraint(name, type)); }
+
+    bool isEmpty() const final { return true; }
+    bool isMandatory() const final { return false; }
+
+private:
+    explicit UnknownConstraint(const String&amp; name, MediaConstraintType type)
+        : MediaConstraint(name, type)
+    {
+    }
+};
+
</ins><span class="cx"> using MediaTrackConstraintSetMap = HashMap&lt;String, RefPtr&lt;MediaConstraint&gt;&gt;;
</span><span class="cx"> 
</span><span class="cx"> class MediaConstraints : public RefCounted&lt;MediaConstraints&gt; {
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformmediastreamMediaStreamTrackPrivatecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp (205347 => 205348)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp        2016-09-02 17:28:00 UTC (rev 205347)
+++ trunk/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp        2016-09-02 17:36:29 UTC (rev 205348)
</span><span class="lines">@@ -172,10 +172,9 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void MediaStreamTrackPrivate::applyConstraints(const MediaConstraints&amp;)
</del><ins>+void MediaStreamTrackPrivate::applyConstraints(const MediaConstraints&amp; constraints, RealtimeMediaSource::SuccessHandler successHandler, RealtimeMediaSource::FailureHandler failureHandler)
</ins><span class="cx"> {
</span><del>-    // FIXME: apply the new constraints to the track
-    // https://bugs.webkit.org/show_bug.cgi?id=122428
</del><ins>+    m_source-&gt;applyConstraints(constraints, successHandler, failureHandler);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> AudioSourceProvider* MediaStreamTrackPrivate::audioSourceProvider()
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformmediastreamMediaStreamTrackPrivateh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h (205347 => 205348)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h        2016-09-02 17:28:00 UTC (rev 205347)
+++ trunk/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h        2016-09-02 17:36:29 UTC (rev 205348)
</span><span class="lines">@@ -91,7 +91,7 @@
</span><span class="cx">     RefPtr&lt;RealtimeMediaSourceCapabilities&gt; capabilities() const;
</span><span class="cx"> 
</span><span class="cx">     RefPtr&lt;MediaConstraints&gt; constraints() const;
</span><del>-    void applyConstraints(const MediaConstraints&amp;);
</del><ins>+    void applyConstraints(const MediaConstraints&amp;, RealtimeMediaSource::SuccessHandler, RealtimeMediaSource::FailureHandler);
</ins><span class="cx"> 
</span><span class="cx">     AudioSourceProvider* audioSourceProvider();
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformmediastreamRealtimeMediaSourcecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/mediastream/RealtimeMediaSource.cpp (205347 => 205348)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/mediastream/RealtimeMediaSource.cpp        2016-09-02 17:28:00 UTC (rev 205347)
+++ trunk/Source/WebCore/platform/mediastream/RealtimeMediaSource.cpp        2016-09-02 17:36:29 UTC (rev 205348)
</span><span class="lines">@@ -36,13 +36,18 @@
</span><span class="cx"> #if ENABLE(MEDIA_STREAM)
</span><span class="cx"> #include &quot;RealtimeMediaSource.h&quot;
</span><span class="cx"> 
</span><ins>+#include &quot;MediaConstraints.h&quot;
+#include &quot;NotImplemented.h&quot;
</ins><span class="cx"> #include &quot;RealtimeMediaSourceCapabilities.h&quot;
</span><span class="cx"> #include &quot;UUID.h&quot;
</span><ins>+#include &lt;wtf/MainThread.h&gt;
+#include &lt;wtf/text/StringHash.h&gt;
</ins><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><span class="cx"> RealtimeMediaSource::RealtimeMediaSource(const String&amp; id, Type type, const String&amp; name)
</span><del>-    : m_id(id)
</del><ins>+    : m_weakPtrFactory(this)
+    , m_id(id)
</ins><span class="cx">     , m_type(type)
</span><span class="cx">     , m_name(name)
</span><span class="cx"> {
</span><span class="lines">@@ -51,6 +56,7 @@
</span><span class="cx">     if (m_id.isEmpty())
</span><span class="cx">         m_id = createCanonicalUUIDString();
</span><span class="cx">     m_persistentID = m_id;
</span><ins>+    m_suppressNotifications = false;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void RealtimeMediaSource::reset()
</span><span class="lines">@@ -92,8 +98,18 @@
</span><span class="cx"> 
</span><span class="cx"> void RealtimeMediaSource::settingsDidChange()
</span><span class="cx"> {
</span><del>-    for (auto&amp; observer : m_observers)
-        observer-&gt;sourceSettingsChanged();
</del><ins>+    ASSERT(isMainThread());
+
+    if (m_pendingSettingsDidChangeNotification || m_suppressNotifications)
+        return;
+
+    m_pendingSettingsDidChangeNotification = true;
+
+    scheduleDeferredTask([this] {
+        m_pendingSettingsDidChangeNotification = false;
+        for (auto&amp; observer : m_observers)
+            observer-&gt;sourceSettingsChanged();
+    });
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void RealtimeMediaSource::mediaDataUpdated(MediaSample&amp; mediaSample)
</span><span class="lines">@@ -134,6 +150,418 @@
</span><span class="cx">     stop(callingObserver);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+RealtimeMediaSource::ConstraintSupport RealtimeMediaSource::supportsConstraint(const MediaConstraint&amp; constraint)
+{
+    RealtimeMediaSourceCapabilities&amp; capabilities = *this-&gt;capabilities();
+
+    switch (constraint.type()) {
+    case MediaConstraintType::Width: {
+        if (!capabilities.supportsWidth())
+            return ConstraintSupport::Ignored;
+
+        auto widthRange = capabilities.width();
+        return constraint.validForRange(widthRange.rangeMin().asInt, widthRange.rangeMax().asInt) ? ConstraintSupport::Supported : ConstraintSupport::Unsupported;
+        break;
+    }
+
+    case MediaConstraintType::Height: {
+        if (!capabilities.supportsHeight())
+            return ConstraintSupport::Ignored;
+
+        auto heightRange = capabilities.height();
+        return constraint.validForRange(heightRange.rangeMin().asInt, heightRange.rangeMax().asInt) ? ConstraintSupport::Supported : ConstraintSupport::Unsupported;
+        break;
+    }
+
+    case MediaConstraintType::FrameRate: {
+        if (!capabilities.supportsFrameRate())
+            return ConstraintSupport::Ignored;
+
+        auto rateRange = capabilities.frameRate();
+        return constraint.validForRange(rateRange.rangeMin().asDouble, rateRange.rangeMax().asDouble) ? ConstraintSupport::Supported : ConstraintSupport::Unsupported;
+        break;
+    }
+
+    case MediaConstraintType::AspectRatio: {
+        if (!capabilities.supportsAspectRatio())
+            return ConstraintSupport::Ignored;
+
+        auto range = capabilities.aspectRatio();
+        return constraint.validForRange(range.rangeMin().asDouble, range.rangeMax().asDouble) ? ConstraintSupport::Supported : ConstraintSupport::Unsupported;
+        break;
+    }
+
+    case MediaConstraintType::Volume: {
+        if (!capabilities.supportsVolume())
+            return ConstraintSupport::Ignored;
+
+        auto range = capabilities.volume();
+        return constraint.validForRange(range.rangeMin().asDouble, range.rangeMax().asDouble) ? ConstraintSupport::Supported : ConstraintSupport::Unsupported;
+        break;
+    }
+
+    case MediaConstraintType::SampleRate: {
+        if (!capabilities.supportsSampleRate())
+            return ConstraintSupport::Ignored;
+
+        auto range = capabilities.sampleRate();
+        return constraint.validForRange(range.rangeMin().asDouble, range.rangeMax().asDouble) ? ConstraintSupport::Supported : ConstraintSupport::Unsupported;
+        break;
+    }
+
+    case MediaConstraintType::SampleSize: {
+        if (!capabilities.supportsSampleSize())
+            return ConstraintSupport::Ignored;
+
+        auto range = capabilities.sampleSize();
+        return constraint.validForRange(range.rangeMin().asDouble, range.rangeMax().asDouble) ? ConstraintSupport::Supported : ConstraintSupport::Unsupported;
+        break;
+    }
+
+    case MediaConstraintType::FacingMode: {
+        if (!capabilities.supportsFacingMode())
+            return ConstraintSupport::Ignored;
+
+        ConstraintSupport support = ConstraintSupport::Ignored;
+        auto&amp; supportedModes = capabilities.facingMode();
+        std::function&lt;bool(MediaConstraint::ConstraintType, const String&amp;)&gt; filter = [supportedModes, &amp;support](MediaConstraint::ConstraintType type, const String&amp; modeString) {
+            if (type == MediaConstraint::ConstraintType::ExactConstraint)
+                support = ConstraintSupport::Unsupported;
+
+            auto mode = RealtimeMediaSourceSettings::videoFacingModeEnum(modeString);
+            for (auto&amp; supportedMode : supportedModes) {
+                if (supportedMode == mode) {
+                    support = ConstraintSupport::Supported;
+                    break;
+                }
+            }
+
+            return type == MediaConstraint::ConstraintType::ExactConstraint ? true : false;
+        };
+
+        constraint.find(filter);
+        return support;
+        break;
+    }
+
+    case MediaConstraintType::EchoCancellation:
+        if (!capabilities.supportsEchoCancellation())
+            return ConstraintSupport::Ignored;
+
+        if (capabilities.echoCancellation() == RealtimeMediaSourceCapabilities::EchoCancellation::ReadOnly)
+            return constraint.isMandatory() ? ConstraintSupport::Unsupported : ConstraintSupport::Ignored;
+
+        return ConstraintSupport::Supported;
+        break;
+
+    case MediaConstraintType::DeviceId: {
+        if (!capabilities.supportsDeviceId())
+            return ConstraintSupport::Ignored;
+
+        ConstraintSupport support = ConstraintSupport::Ignored;
+        std::function&lt;bool(MediaConstraint::ConstraintType, const String&amp;)&gt; filter = [this, &amp;support](MediaConstraint::ConstraintType type, const String&amp; idString) {
+            if (type != MediaConstraint::ConstraintType::ExactConstraint)
+                return false; // Keep looking.
+
+            support = idString == m_id ? ConstraintSupport::Supported : ConstraintSupport::Unsupported;
+            return false;
+        };
+
+        constraint.find(filter);
+        return support;
+        break;
+    }
+
+    case MediaConstraintType::GroupId: {
+        if (!capabilities.supportsDeviceId())
+            return ConstraintSupport::Ignored;
+
+        ConstraintSupport support = ConstraintSupport::Ignored;
+        String groupId = settings().groupId();
+        std::function&lt;bool(MediaConstraint::ConstraintType, const String&amp;)&gt; filter = [groupId, &amp;support](MediaConstraint::ConstraintType type, const String&amp; idString) {
+            if (type != MediaConstraint::ConstraintType::ExactConstraint)
+                return false; // Keep looking.
+
+            support = idString == groupId ? ConstraintSupport::Supported : ConstraintSupport::Unsupported;
+            return false;
+        };
+
+        constraint.find(filter);
+        return support;
+        break;
+    }
+
+    case MediaConstraintType::Unknown:
+        // Unknown (or unsupported) constraints should be ignored.
+        break;
+    }
+
+    return ConstraintSupport::Ignored;
+}
+
+
+template &lt;typename T&gt;
+T value(const MediaConstraint&amp; constraint, T rangeMin, T rangeMax)
+{
+    T result;
+
+    if (constraint.getExact(result)) {
+        ASSERT(result &gt;= rangeMin &amp;&amp; result &lt;= rangeMax);
+        return result;
+    }
+
+    if (constraint.getIdeal(result)) {
+        if (result &lt; rangeMin)
+            result = rangeMin;
+        else if (result &gt; rangeMax)
+            result = rangeMax;
+
+        return result;
+    }
+
+    if (constraint.getMin(result) &amp;&amp; result &gt; rangeMax)
+        return false;
+
+    if (constraint.getMax(result) &amp;&amp; result &lt; rangeMin)
+        return false;
+    
+    return result;
+}
+
+
+void RealtimeMediaSource::applyConstraint(const MediaConstraint&amp; constraint)
+{
+    RealtimeMediaSourceCapabilities&amp; capabilities = *this-&gt;capabilities();
+    switch (constraint.type()) {
+    case MediaConstraintType::Width: {
+        if (!capabilities.supportsWidth())
+            return;
+
+        auto widthRange = capabilities.width();
+        setWidth(value(constraint, widthRange.rangeMin().asInt, widthRange.rangeMax().asInt));
+        break;
+    }
+
+    case MediaConstraintType::Height: {
+        if (!capabilities.supportsHeight())
+            return;
+
+        auto heightRange = capabilities.height();
+        setHeight(value(constraint, heightRange.rangeMin().asInt, heightRange.rangeMax().asInt));
+        break;
+    }
+
+    case MediaConstraintType::FrameRate: {
+        if (!capabilities.supportsFrameRate())
+            return;
+
+        auto rateRange = capabilities.frameRate();
+        setFrameRate(value(constraint, rateRange.rangeMin().asDouble, rateRange.rangeMax().asDouble));
+        break;
+    }
+
+    case MediaConstraintType::AspectRatio: {
+        if (!capabilities.supportsAspectRatio())
+            return;
+
+        auto range = capabilities.aspectRatio();
+        setAspectRatio(value(constraint, range.rangeMin().asDouble, range.rangeMax().asDouble));
+        break;
+    }
+
+    case MediaConstraintType::Volume: {
+        if (!capabilities.supportsVolume())
+            return;
+
+        auto range = capabilities.volume();
+        // std::pair&lt;T, T&gt; valuesForRange(constraint, range.rangeMin().asDouble, range.rangeMax().asDouble)
+        setVolume(value(constraint, range.rangeMin().asDouble, range.rangeMax().asDouble));
+        break;
+    }
+
+    case MediaConstraintType::SampleRate: {
+        if (!capabilities.supportsSampleRate())
+            return;
+
+        auto range = capabilities.sampleRate();
+        setSampleRate(value(constraint, range.rangeMin().asDouble, range.rangeMax().asDouble));
+        break;
+    }
+
+    case MediaConstraintType::SampleSize: {
+        if (!capabilities.supportsSampleSize())
+            return;
+
+        auto range = capabilities.sampleSize();
+        setSampleSize(value(constraint, range.rangeMin().asDouble, range.rangeMax().asDouble));
+        break;
+    }
+
+    case MediaConstraintType::EchoCancellation:
+        if (!capabilities.supportsEchoCancellation())
+            return;
+
+        bool setting;
+        if (constraint.getExact(setting) || constraint.getIdeal(setting))
+            setEchoCancellation(setting);
+        break;
+
+    case MediaConstraintType::FacingMode: {
+        if (!capabilities.supportsFacingMode())
+            return;
+
+        auto&amp; supportedModes = capabilities.facingMode();
+        std::function&lt;bool(MediaConstraint::ConstraintType, const String&amp;)&gt; filter = [supportedModes](MediaConstraint::ConstraintType, const String&amp; modeString) {
+            auto mode = RealtimeMediaSourceSettings::videoFacingModeEnum(modeString);
+            for (auto&amp; supportedMode : supportedModes) {
+                if (mode == supportedMode)
+                    return true;
+            }
+            return false;
+        };
+
+        auto modeString = constraint.find(filter);
+        if (!modeString.isEmpty())
+            setFacingMode(RealtimeMediaSourceSettings::videoFacingModeEnum(modeString));
+        break;
+    }
+
+    case MediaConstraintType::DeviceId:
+    case MediaConstraintType::GroupId:
+        // There is nothing to do here, neither can be changed.
+        break;
+
+    case MediaConstraintType::Unknown:
+        break;
+    }
+}
+
+void RealtimeMediaSource::applyConstraints(const MediaConstraints&amp; constraints, SuccessHandler successHandler, FailureHandler failureHandler)
+{
+    ASSERT(constraints.isValid());
+
+    auto&amp; mandatoryConstraints = constraints.mandatoryConstraints();
+    for (auto&amp; nameConstraintPair : mandatoryConstraints) {
+        auto&amp; constraint = *nameConstraintPair.value;
+        if (supportsConstraint(constraint) == ConstraintSupport::Unsupported) {
+            failureHandler(constraint.name(), &quot;Constraint not supported&quot;);
+            return;
+        }
+    }
+
+    for (auto&amp; nameConstraintPair : mandatoryConstraints)
+        applyConstraint(*nameConstraintPair.value);
+
+    successHandler();
+}
+
+void RealtimeMediaSource::setWidth(int width)
+{
+    if (width == m_size.width())
+        return;
+
+    int height = m_aspectRatio ? width / m_aspectRatio : m_size.height();
+    if (!applySize(IntSize(width, height)))
+        return;
+
+    m_size.setWidth(width);
+    if (m_aspectRatio)
+        m_size.setHeight(width / m_aspectRatio);
+
+    settingsDidChange();
+}
+
+void RealtimeMediaSource::setHeight(int height)
+{
+    if (height == m_size.height())
+        return;
+
+    int width = m_aspectRatio ? height * m_aspectRatio : m_size.width();
+    if (!applySize(IntSize(width, height)))
+        return;
+
+    if (m_aspectRatio)
+        m_size.setWidth(width);
+    m_size.setHeight(height);
+
+    settingsDidChange();
+}
+
+void RealtimeMediaSource::setFrameRate(double rate)
+{
+    if (m_frameRate == rate || !applyFrameRate(rate))
+        return;
+
+    m_frameRate = rate;
+    settingsDidChange();
+}
+
+void RealtimeMediaSource::setAspectRatio(double ratio)
+{
+    if (m_aspectRatio == ratio || !applyAspectRatio(ratio))
+        return;
+
+    m_aspectRatio = ratio;
+    m_size.setHeight(m_size.width() / ratio);
+    settingsDidChange();
+}
+
+void RealtimeMediaSource::setFacingMode(RealtimeMediaSourceSettings::VideoFacingMode mode)
+{
+    if (m_facingMode == mode || !applyFacingMode(mode))
+        return;
+
+    m_facingMode = mode;
+    settingsDidChange();
+}
+
+void RealtimeMediaSource::setVolume(double volume)
+{
+    if (m_volume == volume || !applyVolume(volume))
+        return;
+
+    m_volume = volume;
+    settingsDidChange();
+}
+
+void RealtimeMediaSource::setSampleRate(double rate)
+{
+    if (m_sampleRate == rate || !applySampleRate(rate))
+        return;
+
+    m_sampleRate = rate;
+    settingsDidChange();
+}
+
+void RealtimeMediaSource::setSampleSize(double size)
+{
+    if (m_sampleSize == size || !applySampleSize(size))
+        return;
+
+    m_sampleSize = size;
+    settingsDidChange();
+}
+
+void RealtimeMediaSource::setEchoCancellation(bool echoCancellation)
+{
+    if (m_echoCancellation == echoCancellation || !applyEchoCancellation(echoCancellation))
+        return;
+
+    m_echoCancellation = echoCancellation;
+    settingsDidChange();
+}
+
+void RealtimeMediaSource::scheduleDeferredTask(std::function&lt;void()&gt;&amp;&amp; function)
+{
+    ASSERT(function);
+    callOnMainThread([weakThis = createWeakPtr(), function = WTFMove(function)] {
+        if (!weakThis)
+            return;
+
+        function();
+    });
+}
+
</ins><span class="cx"> } // namespace WebCore
</span><span class="cx"> 
</span><span class="cx"> #endif // ENABLE(MEDIA_STREAM)
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformmediastreamRealtimeMediaSourceh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/mediastream/RealtimeMediaSource.h (205347 => 205348)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/mediastream/RealtimeMediaSource.h        2016-09-02 17:28:00 UTC (rev 205347)
+++ trunk/Source/WebCore/platform/mediastream/RealtimeMediaSource.h        2016-09-02 17:36:29 UTC (rev 205348)
</span><span class="lines">@@ -42,8 +42,10 @@
</span><span class="cx"> #include &quot;MediaSample.h&quot;
</span><span class="cx"> #include &quot;PlatformLayer.h&quot;
</span><span class="cx"> #include &quot;RealtimeMediaSourceCapabilities.h&quot;
</span><ins>+#include &lt;wtf/Lock.h&gt;
</ins><span class="cx"> #include &lt;wtf/RefCounted.h&gt;
</span><span class="cx"> #include &lt;wtf/Vector.h&gt;
</span><ins>+#include &lt;wtf/WeakPtr.h&gt;
</ins><span class="cx"> #include &lt;wtf/text/WTFString.h&gt;
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="lines">@@ -50,7 +52,6 @@
</span><span class="cx"> 
</span><span class="cx"> class FloatRect;
</span><span class="cx"> class GraphicsContext;
</span><del>-class MediaConstraints;
</del><span class="cx"> class MediaStreamPrivate;
</span><span class="cx"> class RealtimeMediaSourceSettings;
</span><span class="cx"> 
</span><span class="lines">@@ -90,7 +91,12 @@
</span><span class="cx"> 
</span><span class="cx">     virtual RefPtr&lt;RealtimeMediaSourceCapabilities&gt; capabilities() = 0;
</span><span class="cx">     virtual const RealtimeMediaSourceSettings&amp; settings() = 0;
</span><del>-    void settingsDidChange();
</del><ins>+
+    using SuccessHandler = std::function&lt;void()&gt;;
+    using FailureHandler = std::function&lt;void(const String&amp; badConstraint, const String&amp; errorString)&gt;;
+    void applyConstraints(const MediaConstraints&amp;, SuccessHandler, FailureHandler);
+
+    virtual void settingsDidChange();
</ins><span class="cx">     void mediaDataUpdated(MediaSample&amp;);
</span><span class="cx">     
</span><span class="cx">     bool stopped() const { return m_stopped; }
</span><span class="lines">@@ -122,23 +128,76 @@
</span><span class="cx">     virtual RefPtr&lt;Image&gt; currentFrameImage() { return nullptr; }
</span><span class="cx">     virtual void paintCurrentFrameInContext(GraphicsContext&amp;, const FloatRect&amp;) { }
</span><span class="cx"> 
</span><ins>+    void setWidth(int);
+    void setHeight(int);
+    const IntSize&amp; size() const { return m_size; }
+    virtual bool applySize(const IntSize&amp;) { return false; }
+
+    double frameRate() const { return m_frameRate; }
+    void setFrameRate(double);
+    virtual bool applyFrameRate(double) { return false; }
+
+    double aspectRatio() const { return m_aspectRatio; }
+    void setAspectRatio(double);
+    virtual bool applyAspectRatio(double) { return false; }
+
+    RealtimeMediaSourceSettings::VideoFacingMode facingMode() const { return m_facingMode; }
+    void setFacingMode(RealtimeMediaSourceSettings::VideoFacingMode);
+    virtual bool applyFacingMode(RealtimeMediaSourceSettings::VideoFacingMode) { return false; }
+
+    double volume() const { return m_volume; }
+    void setVolume(double);
+    virtual bool applyVolume(double) { return false; }
+
+    double sampleRate() const { return m_sampleRate; }
+    void setSampleRate(double);
+    virtual bool applySampleRate(double) { return false; }
+
+    double sampleSize() const { return m_sampleSize; }
+    void setSampleSize(double);
+    virtual bool applySampleSize(double) { return false; }
+
+    bool echoCancellation() const { return m_echoCancellation; }
+    void setEchoCancellation(bool);
+    virtual bool applyEchoCancellation(bool) { return false; }
+
</ins><span class="cx"> protected:
</span><span class="cx">     RealtimeMediaSource(const String&amp; id, Type, const String&amp; name);
</span><span class="cx"> 
</span><ins>+    void scheduleDeferredTask(std::function&lt;void()&gt;&amp;&amp;);
+
</ins><span class="cx">     bool m_muted { false };
</span><span class="cx"> 
</span><span class="cx"> private:
</span><ins>+    WeakPtr&lt;RealtimeMediaSource&gt; createWeakPtr() { return m_weakPtrFactory.createWeakPtr(); }
+
+    enum ConstraintSupport { Ignored, Supported, Unsupported };
+    ConstraintSupport supportsConstraint(const MediaConstraint&amp;);
+    void applyConstraint(const MediaConstraint&amp;);
+
+    WeakPtrFactory&lt;RealtimeMediaSource&gt; m_weakPtrFactory;
+    Lock m_lock;
+
</ins><span class="cx">     String m_id;
</span><span class="cx">     String m_persistentID;
</span><span class="cx">     Type m_type;
</span><span class="cx">     String m_name;
</span><del>-    bool m_stopped { false };
</del><span class="cx">     Vector&lt;Observer*&gt; m_observers;
</span><ins>+    IntSize m_size;
+    double m_frameRate { 30 };
+    double m_aspectRatio { 0 };
+    double m_volume { 1 };
+    double m_sampleRate { 0 };
+    double m_sampleSize { 0 };
+    unsigned m_fitnessScore { 0 };
+    RealtimeMediaSourceSettings::VideoFacingMode m_facingMode { RealtimeMediaSourceSettings::User};
</ins><span class="cx"> 
</span><ins>+    bool m_echoCancellation { false };
+    bool m_stopped { false };
</ins><span class="cx">     bool m_readonly { false };
</span><span class="cx">     bool m_remote { false };
</span><del>-    
-    unsigned m_fitnessScore { 0 };
</del><ins>+    bool m_pendingSettingsDidChangeNotification { false };
+    bool m_suppressNotifications { true };
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformmediastreamRealtimeMediaSourceCapabilitiesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/mediastream/RealtimeMediaSourceCapabilities.h (205347 => 205348)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/mediastream/RealtimeMediaSourceCapabilities.h        2016-09-02 17:28:00 UTC (rev 205347)
+++ trunk/Source/WebCore/platform/mediastream/RealtimeMediaSourceCapabilities.h        2016-09-02 17:36:29 UTC (rev 205348)
</span><span class="lines">@@ -48,7 +48,7 @@
</span><span class="cx">     Type type() const { return m_type; }
</span><span class="cx"> 
</span><span class="cx">     union ValueUnion {
</span><del>-        unsigned long asULong;
</del><ins>+        int asInt;
</ins><span class="cx">         double asDouble;
</span><span class="cx">     };
</span><span class="cx"> 
</span><span class="lines">@@ -63,10 +63,10 @@
</span><span class="cx">         m_minOrValue.asDouble = value;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    CapabilityValueOrRange(unsigned long value)
</del><ins>+    CapabilityValueOrRange(int value)
</ins><span class="cx">         : m_type(ULong)
</span><span class="cx">     {
</span><del>-        m_minOrValue.asULong = value;
</del><ins>+        m_minOrValue.asInt = value;
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     CapabilityValueOrRange(double min, double max)
</span><span class="lines">@@ -76,11 +76,11 @@
</span><span class="cx">         m_max.asDouble = max;
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    CapabilityValueOrRange(unsigned long min, unsigned long max)
</del><ins>+    CapabilityValueOrRange(int min, int max)
</ins><span class="cx">         : m_type(ULongRange)
</span><span class="cx">     {
</span><del>-        m_minOrValue.asULong = min;
-        m_max.asULong = max;
</del><ins>+        m_minOrValue.asInt = min;
+        m_max.asInt = max;
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     const ValueUnion&amp; rangeMin() const
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformmediastreamRealtimeMediaSourceSettingscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/mediastream/RealtimeMediaSourceSettings.cpp (205347 => 205348)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/mediastream/RealtimeMediaSourceSettings.cpp        2016-09-02 17:28:00 UTC (rev 205347)
+++ trunk/Source/WebCore/platform/mediastream/RealtimeMediaSourceSettings.cpp        2016-09-02 17:36:29 UTC (rev 205348)
</span><span class="lines">@@ -37,22 +37,40 @@
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><del>-const AtomicString&amp; RealtimeMediaSourceSettings::facingMode(RealtimeMediaSourceSettings::VideoFacingMode mode)
</del><ins>+static const AtomicString&amp; userFacing()
</ins><span class="cx"> {
</span><span class="cx">     static NeverDestroyed&lt;AtomicString&gt; userFacing(&quot;user&quot;, AtomicString::ConstructFromLiteral);
</span><ins>+    return userFacing;
+}
+static const AtomicString&amp; environmentFacing()
+{
</ins><span class="cx">     static NeverDestroyed&lt;AtomicString&gt; environmentFacing(&quot;environment&quot;, AtomicString::ConstructFromLiteral);
</span><ins>+    return environmentFacing;
+}
+
+static const AtomicString&amp; leftFacing()
+{
</ins><span class="cx">     static NeverDestroyed&lt;AtomicString&gt; leftFacing(&quot;left&quot;, AtomicString::ConstructFromLiteral);
</span><ins>+    return leftFacing;
+}
+
+static const AtomicString&amp; rightFacing()
+{
</ins><span class="cx">     static NeverDestroyed&lt;AtomicString&gt; rightFacing(&quot;right&quot;, AtomicString::ConstructFromLiteral);
</span><del>-    
</del><ins>+    return rightFacing;
+}
+
+const AtomicString&amp; RealtimeMediaSourceSettings::facingMode(RealtimeMediaSourceSettings::VideoFacingMode mode)
+{
</ins><span class="cx">     switch (mode) {
</span><span class="cx">     case RealtimeMediaSourceSettings::User:
</span><del>-        return userFacing;
</del><ins>+        return userFacing();
</ins><span class="cx">     case RealtimeMediaSourceSettings::Environment:
</span><del>-        return environmentFacing;
</del><ins>+        return environmentFacing();
</ins><span class="cx">     case RealtimeMediaSourceSettings::Left:
</span><del>-        return leftFacing;
</del><ins>+        return leftFacing();
</ins><span class="cx">     case RealtimeMediaSourceSettings::Right:
</span><del>-        return rightFacing;
</del><ins>+        return rightFacing();
</ins><span class="cx">     case RealtimeMediaSourceSettings::Unknown:
</span><span class="cx">         return emptyAtom;
</span><span class="cx">     }
</span><span class="lines">@@ -61,6 +79,20 @@
</span><span class="cx">     return emptyAtom;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+RealtimeMediaSourceSettings::VideoFacingMode RealtimeMediaSourceSettings::videoFacingModeEnum(const String&amp; mode)
+{
+    if (mode == userFacing())
+        return RealtimeMediaSourceSettings::User;
+    if (mode == environmentFacing())
+        return RealtimeMediaSourceSettings::Environment;
+    if (mode == leftFacing())
+        return RealtimeMediaSourceSettings::Left;
+    if (mode == rightFacing())
+        return RealtimeMediaSourceSettings::Right;
+
+    return RealtimeMediaSourceSettings::Unknown;
+}
+
</ins><span class="cx"> } // namespace WebCore
</span><span class="cx"> 
</span><span class="cx"> #endif // ENABLE(MEDIA_STREAM)
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformmediastreamRealtimeMediaSourceSettingsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/mediastream/RealtimeMediaSourceSettings.h (205347 => 205348)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/mediastream/RealtimeMediaSourceSettings.h        2016-09-02 17:28:00 UTC (rev 205347)
+++ trunk/Source/WebCore/platform/mediastream/RealtimeMediaSourceSettings.h        2016-09-02 17:36:29 UTC (rev 205348)
</span><span class="lines">@@ -42,6 +42,8 @@
</span><span class="cx"> 
</span><span class="cx">     static const AtomicString&amp; facingMode(RealtimeMediaSourceSettings::VideoFacingMode);
</span><span class="cx"> 
</span><ins>+    static RealtimeMediaSourceSettings::VideoFacingMode videoFacingModeEnum(const String&amp;);
+
</ins><span class="cx">     explicit RealtimeMediaSourceSettings()
</span><span class="cx">     {
</span><span class="cx">     }
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformmediastreammacAVAudioCaptureSourcemm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/mediastream/mac/AVAudioCaptureSource.mm (205347 => 205348)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/mediastream/mac/AVAudioCaptureSource.mm        2016-09-02 17:28:00 UTC (rev 205347)
+++ trunk/Source/WebCore/platform/mediastream/mac/AVAudioCaptureSource.mm        2016-09-02 17:36:29 UTC (rev 205348)
</span><span class="lines">@@ -80,7 +80,7 @@
</span><span class="cx"> void AVAudioCaptureSource::initializeCapabilities(RealtimeMediaSourceCapabilities&amp; capabilities)
</span><span class="cx"> {
</span><span class="cx">     // FIXME: finish this implementation - https://webkit.org/b/122430
</span><del>-    capabilities.setVolume(CapabilityValueOrRange(0, 1.0));
</del><ins>+    capabilities.setVolume(CapabilityValueOrRange(0.0, 1.0));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void AVAudioCaptureSource::initializeSupportedConstraints(RealtimeMediaSourceSupportedConstraints&amp; supportedConstraints)
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformmediastreammacAVMediaCaptureSourceh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/mediastream/mac/AVMediaCaptureSource.h (205347 => 205348)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/mediastream/mac/AVMediaCaptureSource.h        2016-09-02 17:28:00 UTC (rev 205347)
+++ trunk/Source/WebCore/platform/mediastream/mac/AVMediaCaptureSource.h        2016-09-02 17:36:29 UTC (rev 205348)
</span><span class="lines">@@ -33,7 +33,6 @@
</span><span class="cx"> #include &quot;Timer.h&quot;
</span><span class="cx"> #include &lt;wtf/Function.h&gt;
</span><span class="cx"> #include &lt;wtf/RetainPtr.h&gt;
</span><del>-#include &lt;wtf/WeakPtr.h&gt;
</del><span class="cx"> 
</span><span class="cx"> OBJC_CLASS AVCaptureAudioDataOutput;
</span><span class="cx"> OBJC_CLASS AVCaptureConnection;
</span><span class="lines">@@ -63,8 +62,6 @@
</span><span class="cx">     void stopProducingData() override;
</span><span class="cx">     bool isProducingData() const override { return m_isRunning; }
</span><span class="cx"> 
</span><del>-    WeakPtr&lt;AVMediaCaptureSource&gt; createWeakPtr() { return m_weakPtrFactory.createWeakPtr(); }
-
</del><span class="cx"> protected:
</span><span class="cx">     AVMediaCaptureSource(AVCaptureDevice*, const AtomicString&amp;, RealtimeMediaSource::Type, PassRefPtr&lt;MediaConstraints&gt;);
</span><span class="cx"> 
</span><span class="lines">@@ -86,8 +83,6 @@
</span><span class="cx">     void setVideoSampleBufferDelegate(AVCaptureVideoDataOutput*);
</span><span class="cx">     void setAudioSampleBufferDelegate(AVCaptureAudioDataOutput*);
</span><span class="cx"> 
</span><del>-    void scheduleDeferredTask(Function&lt;void ()&gt;&amp;&amp;);
-
</del><span class="cx"> private:
</span><span class="cx">     void setupSession();
</span><span class="cx">     void reset() override;
</span><span class="lines">@@ -94,7 +89,6 @@
</span><span class="cx"> 
</span><span class="cx">     RealtimeMediaSourceSettings m_currentSettings;
</span><span class="cx">     RealtimeMediaSourceSupportedConstraints m_supportedConstraints;
</span><del>-    WeakPtrFactory&lt;AVMediaCaptureSource&gt; m_weakPtrFactory;
</del><span class="cx">     RetainPtr&lt;WebCoreAVMediaCaptureSourceObserver&gt; m_objcObserver;
</span><span class="cx">     RefPtr&lt;MediaConstraints&gt; m_constraints;
</span><span class="cx">     RefPtr&lt;RealtimeMediaSourceCapabilities&gt; m_capabilities;
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformmediastreammacAVMediaCaptureSourcemm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/mediastream/mac/AVMediaCaptureSource.mm (205347 => 205348)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/mediastream/mac/AVMediaCaptureSource.mm        2016-09-02 17:28:00 UTC (rev 205347)
+++ trunk/Source/WebCore/platform/mediastream/mac/AVMediaCaptureSource.mm        2016-09-02 17:36:29 UTC (rev 205348)
</span><span class="lines">@@ -124,7 +124,6 @@
</span><span class="cx"> 
</span><span class="cx"> AVMediaCaptureSource::AVMediaCaptureSource(AVCaptureDeviceTypedef* device, const AtomicString&amp; id, RealtimeMediaSource::Type type, PassRefPtr&lt;MediaConstraints&gt; constraints)
</span><span class="cx">     : RealtimeMediaSource(id, type, emptyString())
</span><del>-    , m_weakPtrFactory(this)
</del><span class="cx">     , m_objcObserver(adoptNS([[WebCoreAVMediaCaptureSourceObserver alloc] initWithCallback:this]))
</span><span class="cx">     , m_constraints(constraints)
</span><span class="cx">     , m_device(device)
</span><span class="lines">@@ -239,17 +238,6 @@
</span><span class="cx">     [audioOutput setSampleBufferDelegate:m_objcObserver.get() queue:globaAudioCaptureSerialQueue()];
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void AVMediaCaptureSource::scheduleDeferredTask(Function&lt;void ()&gt;&amp;&amp; function)
-{
-    ASSERT(function);
-    callOnMainThread([weakThis = createWeakPtr(), function = WTFMove(function)] {
-        if (!weakThis)
-            return;
-
-        function();
-    });
-}
-
</del><span class="cx"> AudioSourceProvider* AVMediaCaptureSource::audioSourceProvider()
</span><span class="cx"> {
</span><span class="cx">     ASSERT_NOT_REACHED();
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformmediastreammacAVVideoCaptureSourceh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/mediastream/mac/AVVideoCaptureSource.h (205347 => 205348)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/mediastream/mac/AVVideoCaptureSource.h        2016-09-02 17:28:00 UTC (rev 205347)
+++ trunk/Source/WebCore/platform/mediastream/mac/AVVideoCaptureSource.h        2016-09-02 17:36:29 UTC (rev 205348)
</span><span class="lines">@@ -57,10 +57,12 @@
</span><span class="cx"> 
</span><span class="cx">     void updateSettings(RealtimeMediaSourceSettings&amp;) override;
</span><span class="cx"> 
</span><ins>+    bool applySize(const IntSize&amp;) override;
+    bool applyFrameRate(double) override;
+
</ins><span class="cx">     void initializeCapabilities(RealtimeMediaSourceCapabilities&amp;) override;
</span><span class="cx">     void initializeSupportedConstraints(RealtimeMediaSourceSupportedConstraints&amp;) override;
</span><span class="cx"> 
</span><del>-    bool applyConstraints(MediaConstraints*);
</del><span class="cx">     bool setFrameRateConstraint(double minFrameRate, double maxFrameRate);
</span><span class="cx"> 
</span><span class="cx">     bool updateFramerate(CMSampleBufferRef);
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformmediastreammacAVVideoCaptureSourcemm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/mediastream/mac/AVVideoCaptureSource.mm (205347 => 205348)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/mediastream/mac/AVVideoCaptureSource.mm        2016-09-02 17:28:00 UTC (rev 205347)
+++ trunk/Source/WebCore/platform/mediastream/mac/AVVideoCaptureSource.mm        2016-09-02 17:36:29 UTC (rev 205348)
</span><span class="lines">@@ -128,91 +128,64 @@
</span><span class="cx">     settings.setAspectRatio(static_cast&lt;float&gt;(m_width) / m_height);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool AVVideoCaptureSource::setFrameRateConstraint(double minFrameRate, double maxFrameRate)
</del><ins>+bool AVVideoCaptureSource::applySize(const IntSize&amp; size)
</ins><span class="cx"> {
</span><del>-    AVFrameRateRange *bestFrameRateRange = 0;
-
-    for (AVFrameRateRange *frameRateRange in [[device() activeFormat] videoSupportedFrameRateRanges]) {
-        if (!maxFrameRate) {
-            if (minFrameRate == [frameRateRange minFrameRate])
-                bestFrameRateRange = frameRateRange;
-        } else if (minFrameRate &gt;= [frameRateRange minFrameRate] &amp;&amp; maxFrameRate &lt;= [frameRateRange maxFrameRate]) {
-            if (CMTIME_COMPARE_INLINE([frameRateRange minFrameDuration], &gt;, [bestFrameRateRange minFrameDuration]))
-                bestFrameRateRange = frameRateRange;
-        }
-    }
-    
-    if (!bestFrameRateRange) {
-        LOG(Media, &quot;AVVideoCaptureSource::setFrameRateConstraint(%p), frame rate range %f..%f not supported by video device&quot;, this, minFrameRate, maxFrameRate);
</del><ins>+    NSString *preset = AVCaptureSessionInfo(session()).bestSessionPresetForVideoDimensions(size.width(), size.height());
+    if (!preset || ![session() canSetSessionPreset:preset]) {
+        LOG(Media, &quot;AVVideoCaptureSource::applySize%p), unable find or set preset for width: %i, height: %i&quot;, this, size.width(), size.height());
</ins><span class="cx">         return false;
</span><span class="cx">     }
</span><del>-    
</del><ins>+
</ins><span class="cx">     NSError *error = nil;
</span><span class="cx">     @try {
</span><del>-        if ([device() lockForConfiguration:&amp;error]) {
-            [device() setActiveVideoMinFrameDuration:[bestFrameRateRange minFrameDuration]];
-            if (maxFrameRate)
-                [device() setActiveVideoMaxFrameDuration:[bestFrameRateRange maxFrameDuration]];
-            [device() unlockForConfiguration];
-        }
</del><ins>+        [session() setSessionPreset:preset];
+
</ins><span class="cx">     } @catch(NSException *exception) {
</span><del>-        LOG(Media, &quot;AVVideoCaptureSource::setFrameRateConstraint(%p), exception thrown configuring device: &lt;%s&gt; %s&quot;, this, [[exception name] UTF8String], [[exception reason] UTF8String]);
</del><ins>+        LOG(Media, &quot;AVVideoCaptureSource::applySize(%p), exception thrown configuring device: &lt;%s&gt; %s&quot;, this, [[exception name] UTF8String], [[exception reason] UTF8String]);
</ins><span class="cx">         return false;
</span><span class="cx">     }
</span><del>-    
</del><ins>+
</ins><span class="cx">     if (error) {
</span><del>-        LOG(Media, &quot;AVVideoCaptureSource::setFrameRateConstraint(%p), failed to lock video device for configuration: %s&quot;, this, [[error localizedDescription] UTF8String]);
</del><ins>+        LOG(Media, &quot;AVVideoCaptureSource::applySize(%p), failed to lock video device for configuration: %s&quot;, this, [[error localizedDescription] UTF8String]);
</ins><span class="cx">         return false;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    LOG(Media, &quot;AVVideoCaptureSource::setFrameRateConstraint(%p) - set frame rate range to %f..%f&quot;, this, minFrameRate, maxFrameRate);
</del><ins>+    LOG(Media, &quot;AVVideoCaptureSource::applySize(%p) - set frame size to %i x %i&quot;, this, size.width(), size.height());
</ins><span class="cx">     return true;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool AVVideoCaptureSource::applyConstraints(MediaConstraints* constraints)
</del><ins>+bool AVVideoCaptureSource::applyFrameRate(double rate)
</ins><span class="cx"> {
</span><del>-    ASSERT(constraints);
</del><ins>+    AVFrameRateRange *bestFrameRateRange = 0;
+    for (AVFrameRateRange *frameRateRange in [[device() activeFormat] videoSupportedFrameRateRanges]) {
+        if (rate &gt;= [frameRateRange minFrameRate] &amp;&amp; rate &lt;= [frameRateRange maxFrameRate]) {
+            if (!bestFrameRateRange || CMTIME_COMPARE_INLINE([frameRateRange minFrameDuration], &gt;, [bestFrameRateRange minFrameDuration]))
+                bestFrameRateRange = frameRateRange;
+        }
+    }
</ins><span class="cx"> 
</span><del>-    // FIXME: Below needs to be refactored for https://bugs.webkit.org/show_bug.cgi?id=160579.
</del><ins>+    if (!bestFrameRateRange) {
+        LOG(Media, &quot;AVVideoCaptureSource::applyFrameRate(%p), frame rate %f not supported by video device&quot;, this, rate);
+        return false;
+    }
</ins><span class="cx"> 
</span><del>-    auto&amp; mandatoryConstraints = constraints-&gt;mandatoryConstraints();
-    int intValue;
-
-    String widthConstraintName = RealtimeMediaSourceSupportedConstraints::nameForConstraint(MediaConstraintType::Width);
-    auto widthConstraint = mandatoryConstraints.get(widthConstraintName);
-    Optional&lt;int&gt; width;
-    if (widthConstraint &amp;&amp; widthConstraint-&gt;getExact(intValue))
-        width = intValue;
-
-    String heightConstraintName = RealtimeMediaSourceSupportedConstraints::nameForConstraint(MediaConstraintType::Height);
-    auto heightConstraint = mandatoryConstraints.get(heightConstraintName);
-    Optional&lt;int&gt; height;
-    if (heightConstraint &amp;&amp; heightConstraint-&gt;getExact(intValue))
-        height = intValue;
-    
-    if (width &amp;&amp; height) {
-        NSString *preset = AVCaptureSessionInfo(session()).bestSessionPresetForVideoDimensions(width.value(), height.value());
-        if (!preset || ![session() canSetSessionPreset:preset]) {
-            LOG(Media, &quot;AVVideoCaptureSource::applyConstraints(%p), unable find or set preset for width: %i, height: %i&quot;, this, width.value(), height.value());
-            return false;
</del><ins>+    NSError *error = nil;
+    @try {
+        if ([device() lockForConfiguration:&amp;error]) {
+            [device() setActiveVideoMinFrameDuration:[bestFrameRateRange minFrameDuration]];
+            [device() unlockForConfiguration];
</ins><span class="cx">         }
</span><del>-
-        [session() setSessionPreset:preset];
</del><ins>+    } @catch(NSException *exception) {
+        LOG(Media, &quot;AVVideoCaptureSource::applyFrameRate(%p), exception thrown configuring device: &lt;%s&gt; %s&quot;, this, [[exception name] UTF8String], [[exception reason] UTF8String]);
+        return false;
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    String frameRateConstraintName = RealtimeMediaSourceSupportedConstraints::nameForConstraint(MediaConstraintType::FrameRate);
-    auto frameRateConstraint = mandatoryConstraints.get(frameRateConstraintName);
-
-    Optional&lt;double&gt; frameRate;
-    double doubleValue;
-    if (frameRateConstraint &amp;&amp; frameRateConstraint-&gt;getExact(doubleValue))
-        frameRate = doubleValue;
-
-    if (frameRate &amp;&amp; !setFrameRateConstraint(frameRate.value(), 0)) {
-        LOG(Media, &quot;AVVideoCaptureSource::applyConstraints(%p), unable set frame rate to %f&quot;, this, frameRate.value());
</del><ins>+    if (error) {
+        LOG(Media, &quot;AVVideoCaptureSource::applyFrameRate(%p), failed to lock video device for configuration: %s&quot;, this, [[error localizedDescription] UTF8String]);
</ins><span class="cx">         return false;
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    LOG(Media, &quot;AVVideoCaptureSource::applyFrameRate(%p) - set frame rate range to %f&quot;, this, rate);
</ins><span class="cx">     return true;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -227,9 +200,6 @@
</span><span class="cx"> 
</span><span class="cx">     [session() addInput:videoIn.get()];
</span><span class="cx"> 
</span><del>-    if (constraints())
-        applyConstraints(constraints());
-
</del><span class="cx">     RetainPtr&lt;AVCaptureVideoDataOutputType&gt; videoOutput = adoptNS([allocAVCaptureVideoDataOutputInstance() init]);
</span><span class="cx">     RetainPtr&lt;NSDictionary&gt; settingsDictionary = adoptNS([[NSDictionary alloc] initWithObjectsAndKeys:
</span><span class="cx">                                                          [NSNumber numberWithInt:kCVPixelFormatType_32BGRA], kCVPixelBufferPixelFormatTypeKey
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformmockMockRealtimeAudioSourcecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/mock/MockRealtimeAudioSource.cpp (205347 => 205348)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/mock/MockRealtimeAudioSource.cpp        2016-09-02 17:28:00 UTC (rev 205347)
+++ trunk/Source/WebCore/platform/mock/MockRealtimeAudioSource.cpp        2016-09-02 17:36:29 UTC (rev 205348)
</span><span class="lines">@@ -59,12 +59,13 @@
</span><span class="cx"> 
</span><span class="cx"> void MockRealtimeAudioSource::updateSettings(RealtimeMediaSourceSettings&amp; settings)
</span><span class="cx"> {
</span><del>-    settings.setVolume(50);
</del><ins>+    settings.setVolume(volume());
+    settings.setEchoCancellation(echoCancellation());
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void MockRealtimeAudioSource::initializeCapabilities(RealtimeMediaSourceCapabilities&amp; capabilities)
</span><span class="cx"> {
</span><del>-    capabilities.setVolume(CapabilityValueOrRange(0, 1.0));
</del><ins>+    capabilities.setVolume(CapabilityValueOrRange(0.0, 1.0));
</ins><span class="cx">     capabilities.setEchoCancellation(RealtimeMediaSourceCapabilities::EchoCancellation::ReadWrite);
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformmockMockRealtimeAudioSourceh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/mock/MockRealtimeAudioSource.h (205347 => 205348)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/mock/MockRealtimeAudioSource.h        2016-09-02 17:28:00 UTC (rev 205347)
+++ trunk/Source/WebCore/platform/mock/MockRealtimeAudioSource.h        2016-09-02 17:36:29 UTC (rev 205348)
</span><span class="lines">@@ -51,6 +51,12 @@
</span><span class="cx">     MockRealtimeAudioSource(const String&amp; name = ASCIILiteral(&quot;Mock audio device&quot;));
</span><span class="cx"> 
</span><span class="cx"> private:
</span><ins>+
+    bool applyVolume(double) override { return true; }
+    bool applySampleRate(double) override { return true; }
+    bool applySampleSize(double) override { return true; }
+    bool applyEchoCancellation(bool) override { return true; }
+
</ins><span class="cx">     void updateSettings(RealtimeMediaSourceSettings&amp;) override;
</span><span class="cx">     void initializeCapabilities(RealtimeMediaSourceCapabilities&amp;) override;
</span><span class="cx">     void initializeSupportedConstraints(RealtimeMediaSourceSupportedConstraints&amp;) override;
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformmockMockRealtimeMediaSourcecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/mock/MockRealtimeMediaSource.cpp (205347 => 205348)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/mock/MockRealtimeMediaSource.cpp        2016-09-02 17:28:00 UTC (rev 205347)
+++ trunk/Source/WebCore/platform/mock/MockRealtimeMediaSource.cpp        2016-09-02 17:36:29 UTC (rev 205348)
</span><span class="lines">@@ -124,7 +124,6 @@
</span><span class="cx">     return m_supportedConstraints;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-
</del><span class="cx"> } // namespace WebCore
</span><span class="cx"> 
</span><span class="cx"> #endif // ENABLE(MEDIA_STREAM)
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformmockMockRealtimeMediaSourceh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/mock/MockRealtimeMediaSource.h (205347 => 205348)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/mock/MockRealtimeMediaSource.h        2016-09-02 17:28:00 UTC (rev 205347)
+++ trunk/Source/WebCore/platform/mock/MockRealtimeMediaSource.h        2016-09-02 17:36:29 UTC (rev 205348)
</span><span class="lines">@@ -37,8 +37,6 @@
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><del>-class FloatRect;
-class GraphicsContext;
</del><span class="cx"> class TrackSourceInfo;
</span><span class="cx"> 
</span><span class="cx"> class MockRealtimeMediaSource : public RealtimeMediaSource {
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformmockMockRealtimeVideoSourcecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/mock/MockRealtimeVideoSource.cpp (205347 => 205348)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/mock/MockRealtimeVideoSource.cpp        2016-09-02 17:28:00 UTC (rev 205347)
+++ trunk/Source/WebCore/platform/mock/MockRealtimeVideoSource.cpp        2016-09-02 17:36:29 UTC (rev 205348)
</span><span class="lines">@@ -65,6 +65,7 @@
</span><span class="cx">     : MockRealtimeMediaSource(createCanonicalUUIDString(), RealtimeMediaSource::Video, name)
</span><span class="cx">     , m_timer(RunLoop::current(), this, &amp;MockRealtimeVideoSource::generateFrame)
</span><span class="cx"> {
</span><ins>+    setFrameRate(30);
</ins><span class="cx">     m_dashWidths.reserveInitialCapacity(2);
</span><span class="cx">     m_dashWidths.uncheckedAppend(6);
</span><span class="cx">     m_dashWidths.uncheckedAppend(6);
</span><span class="lines">@@ -73,11 +74,13 @@
</span><span class="cx"> void MockRealtimeVideoSource::startProducingData()
</span><span class="cx"> {
</span><span class="cx">     MockRealtimeMediaSource::startProducingData();
</span><del>-    if (m_size.isEmpty())
-        setSize(IntSize(640, 480));
</del><ins>+    if (size().isEmpty()) {
+        setWidth(640);
+        setHeight(480);
+    }
</ins><span class="cx"> 
</span><span class="cx">     m_startTime = monotonicallyIncreasingTime();
</span><del>-    m_timer.startRepeating(std::chrono::milliseconds(lround(1000 / m_frameRate)));
</del><ins>+    m_timer.startRepeating(std::chrono::milliseconds(lround(1000 / frameRate())));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void MockRealtimeVideoSource::stopProducingData()
</span><span class="lines">@@ -98,11 +101,13 @@
</span><span class="cx"> 
</span><span class="cx"> void MockRealtimeVideoSource::updateSettings(RealtimeMediaSourceSettings&amp; settings)
</span><span class="cx"> {
</span><del>-    settings.setFacingMode(RealtimeMediaSourceSettings::User);
-    settings.setFrameRate(m_frameRate);
-    settings.setWidth(m_size.width());
-    settings.setHeight(m_size.height());
-    settings.setAspectRatio(static_cast&lt;float&gt;(m_size.width()) / m_size.height());
</del><ins>+    settings.setFacingMode(facingMode());
+    settings.setFrameRate(frameRate());
+    IntSize size = this-&gt;size();
+    settings.setWidth(size.width());
+    settings.setHeight(size.height());
+    if (aspectRatio())
+        settings.setAspectRatio(aspectRatio());
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void MockRealtimeVideoSource::initializeCapabilities(RealtimeMediaSourceCapabilities&amp; capabilities)
</span><span class="lines">@@ -109,8 +114,8 @@
</span><span class="cx"> {
</span><span class="cx">     capabilities.addFacingMode(RealtimeMediaSourceSettings::User);
</span><span class="cx">     capabilities.addFacingMode(RealtimeMediaSourceSettings::Environment);
</span><del>-    capabilities.setWidth(CapabilityValueOrRange(320UL, 1920UL));
-    capabilities.setHeight(CapabilityValueOrRange(240UL, 1080UL));
</del><ins>+    capabilities.setWidth(CapabilityValueOrRange(320, 1920));
+    capabilities.setHeight(CapabilityValueOrRange(240, 1080));
</ins><span class="cx">     capabilities.setFrameRate(CapabilityValueOrRange(15.0, 60.0));
</span><span class="cx">     capabilities.setAspectRatio(CapabilityValueOrRange(4 / 3.0, 16 / 9.0));
</span><span class="cx"> }
</span><span class="lines">@@ -124,26 +129,19 @@
</span><span class="cx">     supportedConstraints.setSupportsFacingMode(true);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void MockRealtimeVideoSource::setFrameRate(float rate)
</del><ins>+bool MockRealtimeVideoSource::applyFrameRate(double rate)
</ins><span class="cx"> {
</span><del>-    if (m_frameRate == rate)
-        return;
-
-    m_frameRate = rate;
</del><span class="cx">     if (m_timer.isActive())
</span><del>-        m_timer.startRepeating(std::chrono::milliseconds(lround(1000 / m_frameRate)));
</del><ins>+        m_timer.startRepeating(std::chrono::milliseconds(lround(1000 / rate)));
</ins><span class="cx"> 
</span><del>-    settingsDidChange();
</del><ins>+    updatePlatformLayer();
+    updateSampleBuffer();
+    return true;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-void MockRealtimeVideoSource::setSize(const IntSize&amp; size)
</del><ins>+bool MockRealtimeVideoSource::applySize(const IntSize&amp; size)
</ins><span class="cx"> {
</span><del>-    if (size == m_size)
-        return;
-
-    m_size = size;
-
-    m_baseFontSize = m_size.height() * .08;
</del><ins>+    m_baseFontSize = size.height() * .08;
</ins><span class="cx">     FontCascadeDescription fontDescription;
</span><span class="cx">     fontDescription.setOneFamily(&quot;Courier&quot;);
</span><span class="cx">     fontDescription.setSpecifiedSize(m_baseFontSize);
</span><span class="lines">@@ -168,13 +166,13 @@
</span><span class="cx">     m_imageBuffer = nullptr;
</span><span class="cx">     updatePlatformLayer();
</span><span class="cx"> 
</span><del>-    settingsDidChange();
</del><ins>+    return true;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void MockRealtimeVideoSource::drawAnimation(GraphicsContext&amp; context)
</span><span class="cx"> {
</span><del>-    float radius = m_size.width() * .09;
-    FloatPoint location(m_size.width() * .8, m_size.height() * .3);
</del><ins>+    float radius = size().width() * .09;
+    FloatPoint location(size().width() * .8, size().height() * .3);
</ins><span class="cx"> 
</span><span class="cx">     m_path.clear();
</span><span class="cx">     m_path.moveTo(location);
</span><span class="lines">@@ -184,7 +182,7 @@
</span><span class="cx">     context.setFillRule(RULE_NONZERO);
</span><span class="cx">     context.fillPath(m_path);
</span><span class="cx"> 
</span><del>-    float endAngle = piFloat * (((fmod(m_frameNumber, m_frameRate) + 0.5) * (2.0 / m_frameRate)) + 1);
</del><ins>+    float endAngle = piFloat * (((fmod(m_frameNumber, frameRate()) + 0.5) * (2.0 / frameRate())) + 1);
</ins><span class="cx">     m_path.clear();
</span><span class="cx">     m_path.moveTo(location);
</span><span class="cx">     m_path.addArc(location, radius, 1.5 * piFloat, endAngle, false);
</span><span class="lines">@@ -202,11 +200,12 @@
</span><span class="cx">     static const RGBA32 red = 0xffff0000;
</span><span class="cx">     static const RGBA32 green = 0xff008000;
</span><span class="cx"> 
</span><del>-    float boxSize = m_size.width() * .035;
-    float boxTop = m_size.height() * .6;
</del><ins>+    IntSize size = this-&gt;size();
+    float boxSize = size.width() * .035;
+    float boxTop = size.height() * .6;
</ins><span class="cx"> 
</span><span class="cx">     m_path.clear();
</span><del>-    FloatRect frameRect(2, 2, m_size.width() - 3, m_size.height() - 3);
</del><ins>+    FloatRect frameRect(2, 2, size.width() - 3, size.height() - 3);
</ins><span class="cx">     context.setStrokeColor(Color::white);
</span><span class="cx">     context.setStrokeThickness(3);
</span><span class="cx">     context.setLineDash(m_dashWidths, 0);
</span><span class="lines">@@ -217,7 +216,7 @@
</span><span class="cx">     context.setLineDash(DashArray(), 0);
</span><span class="cx">     m_path.clear();
</span><span class="cx">     m_path.moveTo(FloatPoint(0, boxTop + boxSize));
</span><del>-    m_path.addLineTo(FloatPoint(m_size.width(), boxTop + boxSize));
</del><ins>+    m_path.addLineTo(FloatPoint(size.width(), boxTop + boxSize));
</ins><span class="cx">     m_path.closeSubpath();
</span><span class="cx">     context.setStrokeColor(Color::white);
</span><span class="cx">     context.setStrokeThickness(2);
</span><span class="lines">@@ -264,7 +263,8 @@
</span><span class="cx">     unsigned minutes = seconds / 60 % 60;
</span><span class="cx">     unsigned hours = minutes / 60 % 60;
</span><span class="cx"> 
</span><del>-    FloatPoint timeLocation(m_size.width() * .05, m_size.height() * .15);
</del><ins>+    IntSize size = this-&gt;size();
+    FloatPoint timeLocation(size.width() * .05, size.height() * .15);
</ins><span class="cx">     context.setFillColor(Color::white);
</span><span class="cx">     context.setTextDrawingMode(TextModeFill);
</span><span class="cx">     String string = String::format(&quot;%02u:%02u:%02u.%03u&quot;, hours, minutes, seconds, milliseconds % 1000);
</span><span class="lines">@@ -274,16 +274,16 @@
</span><span class="cx">     timeLocation.move(0, m_baseFontSize);
</span><span class="cx">     context.drawText(m_timeFont, TextRun((StringView(string))), timeLocation);
</span><span class="cx"> 
</span><del>-    FloatPoint statsLocation(m_size.width() * .65, m_size.height() * .75);
-    string = String::format(&quot;Frame rate: %ufps&quot;, m_frameRate);
</del><ins>+    FloatPoint statsLocation(size.width() * .65, size.height() * .75);
+    string = String::format(&quot;Frame rate: %ffps&quot;, frameRate());
</ins><span class="cx">     context.drawText(m_statsFont, TextRun((StringView(string))), statsLocation);
</span><span class="cx"> 
</span><del>-    string = String::format(&quot;Size: %u x %u&quot;, m_size.width(), m_size.height());
</del><ins>+    string = String::format(&quot;Size: %u x %u&quot;, size.width(), size.height());
</ins><span class="cx">     statsLocation.move(0, m_statsFontSize);
</span><span class="cx">     context.drawText(m_statsFont, TextRun((StringView(string))), statsLocation);
</span><span class="cx"> 
</span><span class="cx">     const char* camera;
</span><del>-    switch (settings().facingMode()) {
</del><ins>+    switch (facingMode()) {
</ins><span class="cx">     case RealtimeMediaSourceSettings::User:
</span><span class="cx">         camera = &quot;User facing&quot;;
</span><span class="cx">         break;
</span><span class="lines">@@ -304,7 +304,7 @@
</span><span class="cx">     statsLocation.move(0, m_statsFontSize);
</span><span class="cx">     context.drawText(m_statsFont, TextRun((StringView(string))), statsLocation);
</span><span class="cx"> 
</span><del>-    FloatPoint bipBopLocation(m_size.width() * .6, m_size.height() * .6);
</del><ins>+    FloatPoint bipBopLocation(size.width() * .6, size.height() * .6);
</ins><span class="cx">     unsigned frameMod = m_frameNumber % 60;
</span><span class="cx">     if (frameMod &lt;= 15) {
</span><span class="cx">         context.setFillColor(Color::gray);
</span><span class="lines">@@ -319,11 +319,16 @@
</span><span class="cx"> 
</span><span class="cx"> void MockRealtimeVideoSource::generateFrame()
</span><span class="cx"> {
</span><del>-    GraphicsContext&amp; context = imageBuffer()-&gt;context();
</del><ins>+    ImageBuffer* buffer = imageBuffer();
+    if (!buffer)
+        return;
+
+    GraphicsContext&amp; context = buffer-&gt;context();
</ins><span class="cx">     GraphicsContextStateSaver stateSaver(context);
</span><span class="cx"> 
</span><del>-    FloatRect frameRect(FloatPoint(), m_size);
-    context.fillRect(FloatRect(FloatPoint(), m_size), Color::black);
</del><ins>+    IntSize size = this-&gt;size();
+    FloatRect frameRect(FloatPoint(), size);
+    context.fillRect(FloatRect(FloatPoint(), size), Color::black);
</ins><span class="cx"> 
</span><span class="cx">     drawText(context);
</span><span class="cx">     drawAnimation(context);
</span><span class="lines">@@ -338,7 +343,7 @@
</span><span class="cx">     if (m_imageBuffer)
</span><span class="cx">         return m_imageBuffer.get();
</span><span class="cx"> 
</span><del>-    m_imageBuffer = ImageBuffer::create(m_size, Unaccelerated);
</del><ins>+    m_imageBuffer = ImageBuffer::create(size(), Unaccelerated);
</ins><span class="cx">     if (!m_imageBuffer)
</span><span class="cx">         return nullptr;
</span><span class="cx"> 
</span><span class="lines">@@ -368,7 +373,6 @@
</span><span class="cx">     return m_imageBuffer-&gt;copyImage(DontCopyBackingStore);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-
</del><span class="cx"> } // namespace WebCore
</span><span class="cx"> 
</span><span class="cx"> #endif // ENABLE(MEDIA_STREAM)
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformmockMockRealtimeVideoSourceh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/mock/MockRealtimeVideoSource.h (205347 => 205348)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/mock/MockRealtimeVideoSource.h        2016-09-02 17:28:00 UTC (rev 205347)
+++ trunk/Source/WebCore/platform/mock/MockRealtimeVideoSource.h        2016-09-02 17:36:29 UTC (rev 205348)
</span><span class="lines">@@ -51,11 +51,6 @@
</span><span class="cx"> 
</span><span class="cx">     virtual ~MockRealtimeVideoSource() { }
</span><span class="cx"> 
</span><del>-    void setSize(const IntSize&amp;);
-    const IntSize&amp; size() const { return m_size; }
-
-    void setFrameRate(float);
-
</del><span class="cx"> protected:
</span><span class="cx">     MockRealtimeVideoSource(const String&amp; name = ASCIILiteral(&quot;Mock video device&quot;));
</span><span class="cx">     virtual void updatePlatformLayer() const { }
</span><span class="lines">@@ -70,13 +65,18 @@
</span><span class="cx">     void initializeCapabilities(RealtimeMediaSourceCapabilities&amp;) override;
</span><span class="cx">     void initializeSupportedConstraints(RealtimeMediaSourceSupportedConstraints&amp;) override;
</span><span class="cx"> 
</span><del>-    void startProducingData() override;
-    void stopProducingData() override;
</del><ins>+    void startProducingData() final;
+    void stopProducingData() final;
</ins><span class="cx"> 
</span><span class="cx">     void drawAnimation(GraphicsContext&amp;);
</span><span class="cx">     void drawText(GraphicsContext&amp;);
</span><span class="cx">     void drawBoxes(GraphicsContext&amp;);
</span><span class="cx"> 
</span><ins>+    bool applySize(const IntSize&amp;) override;
+    bool applyFrameRate(double) override;
+    bool applyFacingMode(RealtimeMediaSourceSettings::VideoFacingMode) override { return true; }
+    bool applyAspectRatio(double) override { return true; }
+
</ins><span class="cx">     PlatformLayer* platformLayer() const override { return nullptr; }
</span><span class="cx">     RefPtr&lt;Image&gt; currentFrameImage() override;
</span><span class="cx">     void paintCurrentFrameInContext(GraphicsContext&amp;, const FloatRect&amp;) override;
</span><span class="lines">@@ -94,7 +94,6 @@
</span><span class="cx"> 
</span><span class="cx">     mutable std::unique_ptr&lt;ImageBuffer&gt; m_imageBuffer;
</span><span class="cx"> 
</span><del>-    IntSize m_size;
</del><span class="cx">     Path m_path;
</span><span class="cx">     DashArray m_dashWidths;
</span><span class="cx"> 
</span><span class="lines">@@ -101,7 +100,6 @@
</span><span class="cx">     double m_startTime { NAN };
</span><span class="cx">     double m_elapsedTime { 0 };
</span><span class="cx"> 
</span><del>-    unsigned m_frameRate { 30 };
</del><span class="cx">     unsigned m_frameNumber { 0 };
</span><span class="cx"> 
</span><span class="cx">     RunLoop::Timer&lt;MockRealtimeVideoSource&gt; m_timer;
</span></span></pre>
</div>
</div>

</body>
</html>