Backed out changeset 445c2952117c (bug 996238)

This commit is contained in:
Carsten "Tomcat" Book 2015-04-01 16:14:00 +02:00
parent 7810f6c0c6
commit be87c8e736
7 changed files with 114 additions and 97 deletions

View File

@ -13,46 +13,6 @@
return good; return good;
} }
function mkElement(type) {
// This makes an unattached element.
// It's not rendered to save the cycles that costs on b2g emulator
// and it gets dropped (and GC'd) when the test is done.
var e = document.createElement(type);
e.width = 32;
e.height = 24;
document.getElementById('display').appendChild(e);
return e;
}
// Runs checkFunc until it reports success.
// This is kludgy, but you have to wait for media to start flowing, and it
// can't be any old media, it has to include real data, for which we have no
// reliable signals to use as a trigger.
function periodicCheck(checkFunc) {
var resolve;
var done = false;
// This returns a function so that we create 10 closures in the loop, not
// one; and so that the timers don't all start straight away
var waitAndCheck = counter => () => {
if (done) {
return Promise.resolve();
}
return new Promise(r => setTimeout(r, 200 << counter))
.then(() => {
if (checkFunc()) {
done = true;
resolve();
}
});
};
var chain = Promise.resolve();
for (var i = 0; i < 10; ++i) {
chain = chain.then(waitAndCheck(i));
}
return new Promise(r => resolve = r);
}
function isSilence(audioData) { function isSilence(audioData) {
var silence = true; var silence = true;
for (var i = 0; i < audioData.length; ++i) { for (var i = 0; i < audioData.length; ++i) {
@ -63,46 +23,97 @@
return silence; return silence;
} }
function checkAudio(constraintApplied, stream) { function periodicCheck(type, checkFunc, successMessage, done) {
var audio = mkElement('audio'); var num = 0;
audio.mozSrcObject = stream; var timeout;
audio.play(); function periodic() {
if (checkFunc()) {
ok(true, type + ' is ' + successMessage);
done();
} else {
setupNext();
}
}
function setupNext() {
// exponential backoff on the timer
// on a very slow system (like the b2g emulator) a long timeout is
// necessary, but we want to run fast if we can
timeout = setTimeout(periodic, 200 << num);
num++;
}
setupNext();
return function cancel() {
if (timeout) {
ok(false, type + ' (' + successMessage + ')' +
' failed after waiting full duration');
clearTimeout(timeout);
done();
}
};
}
function checkAudio(constraintApplied, stream, done) {
var context = new AudioContext(); var context = new AudioContext();
var source = context.createMediaStreamSource(stream); var source = context.createMediaStreamSource(stream);
var analyser = context.createAnalyser(); var analyser = context.createAnalyser();
source.connect(analyser); source.connect(analyser);
analyser.connect(context.destination); analyser.connect(context.destination);
return periodicCheck(() => { function testAudio() {
var sampleCount = analyser.frequencyBinCount; var sampleCount = analyser.frequencyBinCount;
info('got some audio samples: ' + sampleCount); info('got some audio samples: ' + sampleCount);
var buffer = new Uint8Array(sampleCount); var bucket = new ArrayBuffer(sampleCount);
analyser.getByteTimeDomainData(buffer); var view = new Uint8Array(bucket);
analyser.getByteTimeDomainData(view);
var silent = check(constraintApplied, isSilence(buffer), var silent = check(constraintApplied, isSilence(view), 'be silence for audio');
'be silence for audio');
return sampleCount > 0 && silent; return sampleCount > 0 && silent;
}).then(() => { }
function disconnect() {
source.disconnect(); source.disconnect();
analyser.disconnect(); analyser.disconnect();
audio.pause(); done();
ok(true, 'audio is ' + (constraintApplied ? '' : 'not ') + 'silent'); }
}); return periodicCheck('audio', testAudio,
(constraintApplied ? '' : 'not ') + 'silent', disconnect);
} }
function checkVideo(constraintApplied, stream) { function mkElement(type) {
// this makes an unattached element
// it's not rendered to save the cycles that costs on b2g emulator
// and it gets droped (and GC'd) when the test is done
var e = document.createElement(type);
e.width = 32;
e.height = 24;
return e;
}
function checkVideo(constraintApplied, stream, done) {
var video = mkElement('video'); var video = mkElement('video');
video.mozSrcObject = stream; video.mozSrcObject = stream;
var ready = false;
video.onplaying = function() {
ready = true;
}
video.play(); video.play();
return periodicCheck(() => { function tryToRenderToCanvas() {
if (!ready) {
info('waiting for video to start');
return false;
}
try { try {
// every try needs a new canvas, otherwise a taint from an earlier call
// will affect subsequent calls
var canvas = mkElement('canvas'); var canvas = mkElement('canvas');
var ctx = canvas.getContext('2d'); var ctx = canvas.getContext('2d');
// Have to guard drawImage with the try as well, due to bug 879717. If // have to guard drawImage with the try as well, due to bug 879717
// we get an error, this round fails, but that failure is usually just // if we get an error, this round fails, but that failure is usually
// transitory. // just transitory
ctx.drawImage(video, 0, 0); ctx.drawImage(video, 0, 0);
ctx.getImageData(0, 0, 1, 1); ctx.getImageData(0, 0, 1, 1);
return check(constraintApplied, false, 'throw on getImageData for video'); return check(constraintApplied, false, 'throw on getImageData for video');
@ -110,10 +121,10 @@
return check(constraintApplied, e.name === 'SecurityError', return check(constraintApplied, e.name === 'SecurityError',
'get a security error: ' + e.name); 'get a security error: ' + e.name);
} }
}).then(() => { }
video.pause();
ok(true, 'video is ' + (constraintApplied ? '' : 'not ') + 'protected'); return periodicCheck('video', tryToRenderToCanvas,
}); (constraintApplied ? '' : 'not ') + 'protected', done);
} }
global.audioIsSilence = checkAudio; global.audioIsSilence = checkAudio;

View File

@ -0,0 +1 @@
martin@Martins-MacBook-Pro.local.287

View File

@ -23,30 +23,27 @@ function identityPcTest(remoteOptions) {
fake: true, fake: true,
peerIdentity: id1 peerIdentity: id1
}]); }]);
test.pcLocal.setIdentityProvider('test1.example.com', 'idp.js'); test.setIdentityProvider(test.pcLocal, 'test1.example.com', 'idp.html');
test.pcRemote.setIdentityProvider('test2.example.com', 'idp.js'); test.setIdentityProvider(test.pcRemote, 'test2.example.com', 'idp.html');
test.chain.append([ test.chain.append([
function PEER_IDENTITY_IS_SET_CORRECTLY(test) { function PEER_IDENTITY_IS_SET_CORRECTLY(test) {
// no need to wait to check identity in this case, // no need to wait to check identity in this case,
// setRemoteDescription should wait for the IdP to complete // setRemoteDescription should wait for the IdP to complete
function checkIdentity(pc, pfx, idp, name) { function checkIdentity(pc, pfx, idp, name) {
return pc.peerIdentity.then(peerInfo => { is(pc.peerIdentity.idp, idp, pfx + "IdP is correct");
is(peerInfo.idp, idp, pfx + "IdP check"); is(pc.peerIdentity.name, name + "@" + idp, pfx + "identity is correct");
is(peerInfo.name, name + "@" + idp, pfx + "identity check");
});
} }
return Promise.all([ checkIdentity(test.pcLocal._pc, "local: ", "test2.example.com", "someone");
checkIdentity(test.pcLocal._pc, "local: ", "test2.example.com", "someone"), checkIdentity(test.pcRemote._pc, "remote: ", "test1.example.com", "someone");
checkIdentity(test.pcRemote._pc, "remote: ", "test1.example.com", "someone")
]);
}, },
function REMOTE_STREAMS_ARE_RESTRICTED(test) { function REMOTE_STREAMS_ARE_RESTRICTED(test) {
var remoteStream = test.pcLocal._pc.getRemoteStreams()[0]; var remoteStream = test.pcLocal._pc.getRemoteStreams()[0];
return Promise.all([ return Promise.all([
audioIsSilence(true, remoteStream), new Promise(done => audioIsSilence(true, remoteStream, done)),
videoIsBlack(true, remoteStream) new Promise(done => videoIsBlack(true, remoteStream, done))
]); ]);
} }
]); ]);

View File

@ -15,9 +15,9 @@ createHTML({
}); });
function theTest() { function theTest() {
// Override the remote media capture options to remove isolation for the // override the remote media capture options to remove isolation
// remote party; the test verifies that the media it receives on the local // for the remote party; the test verifies that the media it receives
// side is isolated anyway. // on the local side is isolated
identityPcTest({ identityPcTest({
audio: true, audio: true,
video: true, video: true,

View File

@ -28,8 +28,6 @@ const signalingStateTransitions = {
"closed": [] "closed": []
} }
var wait = (time) => new Promise(r => setTimeout(r, time));
/** /**
* This class provides a state checker for media elements which store * This class provides a state checker for media elements which store
* a media stream to check for media attribute state and events fired. * a media stream to check for media attribute state and events fired.
@ -64,8 +62,8 @@ function MediaElementChecker(element) {
// If time has passed, then track that and remove the timeupdate event // If time has passed, then track that and remove the timeupdate event
// listener. // listener.
if (element.mozSrcObject && element.mozSrcObject.currentTime > 0 && if(element.mozSrcObject && element.mozSrcObject.currentTime > 0 &&
element.currentTime > 0) { element.currentTime > 0) {
info('time passed for media element ' + elementId); info('time passed for media element ' + elementId);
this.timePassed = true; this.timePassed = true;
this.element.removeEventListener('timeupdate', timeUpdateCallback, this.element.removeEventListener('timeupdate', timeUpdateCallback,

View File

@ -557,3 +557,5 @@ var addRenegotiationAnswerer = (chain, commands, checks) => {
}); });
addRenegotiation(chain, commands, checks); addRenegotiation(chain, commands, checks);
}; };

View File

@ -7,33 +7,41 @@
<body> <body>
<pre id="test"> <pre id="test">
<script type="application/javascript"> <script type="application/javascript">
createHTML({ createHTML({ title: "Test getUserMedia peerIdentity Constraint", bug: "942367" });
title: "Test getUserMedia peerIdentity Constraint",
bug: "942367"
});
function theTest() { function theTest() {
function testPeerIdentityConstraint(withConstraint) { function testPeerIdentityConstraint(withConstraint, done) {
var config = { audio: true, video: true, fake: true }; var config = { audio: true, video: true, fake: true };
if (withConstraint) { if (withConstraint) {
config.peerIdentity = 'user@example.com'; config.peerIdentity = 'user@example.com';
} }
info('getting media with constraints: ' + JSON.stringify(config)); info('getting media with constraints: ' + JSON.stringify(config));
return getUserMedia(config) navigator.mediaDevices.getUserMedia(config).then(function(stream) {
.then(stream => Promise.all([ var oneDone = false;
audioIsSilence(withConstraint, stream), function checkDone() {
videoIsBlack(withConstraint, stream) if (oneDone) {
])); done();
}
oneDone = true;
}
var cancelAudioCheck = audioIsSilence(withConstraint, stream, checkDone);
var cancelVideoCheck = videoIsBlack(withConstraint, stream, checkDone);
setTimeout(cancelAudioCheck, 3*60*1000);
setTimeout(cancelVideoCheck, 3*60*1000);
})
.catch(function(e) {
ok(false, 'gUM error: ' + e);
});
}; };
// both without and with the constraint // without constraint
testPeerIdentityConstraint(false) testPeerIdentityConstraint(false, function() {
.then(() => testPeerIdentityConstraint(true)) // with the constraint
.catch(e => ok(false, 'error in test: ' + e)) testPeerIdentityConstraint(true, SimpleTest.finish.bind(SimpleTest));
.then(() => SimpleTest.finish()) });
.catch(e => ok(false, 'something is really messed up: ' + e));
} }
runTest(theTest); runTest(theTest);
SimpleTest.waitForExplicitFinish();
</script> </script>
</pre> </pre>