--- /dev/null
+<!DOCTYPE html>
+<html>
+<head>
+ <script src="/resources/js-test-pre.js"></script>
+ <script src="./resources/getUserMedia-helper.js"></script>
+</head>
+<body onload="start()">
+<p id="description"></p>
+<div id="console"></div>
+<video controls width="680" height="360"></video>
+<canvas width="680" height="360"></canvas>
+<script>
+ let canvas;
+ let context;
+ let mediaStream;
+ let video;
+ let havePlayed = false;
+
+ let buffer;
+
+ function isPixelBlack(pixel)
+ {
+ return pixel[0] === 0 && pixel[1] === 0 && pixel[2] === 0 && pixel[3] === 255;
+ }
+
+ function isPixelTransparent(pixel)
+ {
+ return pixel[0] === 0 && pixel[1] === 0 && pixel[2] === 0 && pixel[3] === 0;
+ }
+
+ function isPixelWhite(pixel)
+ {
+ return pixel[0] === 255 && pixel[1] === 255 && pixel[2] === 255 && pixel[3] === 255;
+ }
+
+ function canvasShouldBeBlack()
+ {
+ return !(mediaStream.getVideoTracks()[0].enabled && havePlayed);
+ }
+
+ function attempt(numberOfTries, call, callback)
+ {
+ if (numberOfTries <= 0) {
+ testFailed('Pixel check did not succeed after multiple tries.');
+ return;
+ }
+
+ let attemptSucceeded = call();
+ if (attemptSucceeded) {
+ testPassed(canvasShouldBeBlack() ? 'pixel was black.' : 'pixel was white.');
+ callback();
+
+ return;
+ }
+
+ setTimeout(() => { attempt(--numberOfTries, call, callback); }, 50);
+ }
+
+ function repeatWithVideoPlayingAndFinishTest()
+ {
+ if (video.paused) {
+ debug('<br> ===== play video =====');
+ evalAndLog('video.play()');
+ havePlayed = true;
+ beginTestRound();
+ } else {
+ debug('');
+ video.pause();
+ finishJSTest();
+ }
+ }
+
+ function reenableTrack()
+ {
+ mediaStream.getVideoTracks()[0].enabled = true;
+ debug(`<br> === video track reenabled, should${havePlayed ? "" : " NOT"} render current frame ===`);
+
+ // The video is not guaranteed to render non-black frames before the canvas is drawn to and the pixels are checked.
+ // A timeout is used to ensure that the pixel check is done after the video renders non-black frames.
+ attempt(10, checkPixels, repeatWithVideoPlayingAndFinishTest);
+ }
+
+ function checkPixels()
+ {
+ context.clearRect(0, 0, canvas.width, canvas.height);
+ buffer = context.getImageData(30, 242, 1, 1).data;
+ if (!isPixelTransparent(buffer))
+ testFailed('pixel was not transparent after clearing canvas.');
+
+ context.drawImage(video, 0, 0, canvas.width, canvas.height);
+ buffer = context.getImageData(30, 242, 1, 1).data;
+
+ if (!canvasShouldBeBlack())
+ return isPixelWhite(buffer);
+ else
+ return isPixelBlack(buffer);
+ }
+
+ function disableAllTracks()
+ {
+ mediaStream.getVideoTracks()[0].enabled = false;
+ debug('<br> === all video tracks disabled ===');
+
+ // The video is not guaranteed to render black frames before the canvas is drawn to and the pixels are checked.
+ // A timeout is used to ensure that the pixel check is done after the video renders black frames.
+ attempt(10, checkPixels, reenableTrack);
+ }
+
+ function beginTestRound()
+ {
+ debug('<br> === beginning round of pixel tests ===');
+ attempt(10, checkPixels, disableAllTracks);
+ }
+
+ function canplay()
+ {
+ canvas = document.querySelector('canvas');
+ context = canvas.getContext('2d');
+
+ beginTestRound();
+ }
+
+ function start()
+ {
+ description("Tests that re-enabling a video MediaStreamTrack when all tracks were previously disabled causes captured media to display.");
+
+ video = document.querySelector('video');
+ video.addEventListener('canplay', canplay);
+
+ getUserMedia("allow", {video:true}, setupVideoElementWithStream);
+ }
+
+ window.jsTestIsAsync = true;
+</script>
+<script src="/resources/js-test-post.js"></script>
+</body>
+</html>
--- /dev/null
+function getUserMedia(permission, constraints, successCallback, errorCallback) {
+ if (window.testRunner)
+ testRunner.setUserMediaPermission(permission == "allow");
+ else {
+ debug("This test can not be run without the testRunner");
+ finishJSTest();
+ return;
+ }
+
+ navigator.mediaDevices
+ .getUserMedia(constraints)
+ .then(successCallback, reject)
+ .catch(defaultRejectOrCatch);
+
+ function reject(e) {
+ if (errorCallback)
+ errorCallback(e);
+ else
+ defaultRejectOrCatch(e);
+ }
+}
+
+function defaultRejectOrCatch(e) {
+ testFailed('getUserMedia failed:' + e);
+ finishJSTest();
+}
+
+function setupVideoElementWithStream(stream)
+{
+ mediaStream = stream;
+ testPassed('mediaDevices.getUserMedia generated a stream successfully.');
+ evalAndLog('video.srcObject = mediaStream');
+}
+2017-04-04 Youenn Fablet <youenn@apple.com>
+
+ Canvas is tainted when painting a video with MediaStreamTrack
+ https://bugs.webkit.org/show_bug.cgi?id=170486
+
+ Reviewed by Eric Carlson.
+
+ Test: http/tests/media/media-stream/getusermedia-with-canvas.html
+
+ Adding the notion of isolated source so that we can later on implement WebRTC isolated tracks.
+ For now, canvas will not be tainted if painted from a MediaStreamTrack.
+
+ * platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.h:
+ * platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.mm:
+ (WebCore::MediaPlayerPrivateMediaStreamAVFObjC::didPassCORSAccessCheck):
+ * platform/mediastream/MediaStreamTrackPrivate.h:
+ (WebCore::MediaStreamTrackPrivate::isIsolated):
+ * platform/mediastream/RealtimeMediaSource.h:
+
2017-04-04 Commit Queue <commit-queue@webkit.org>
Unreviewed, rolling out r214894, r214895, r214907, r214912,