// an invertible check on the condition. // if the constraint is applied, then the check is direct // if not applied, then the result should be reversed function check(constraintApplied, condition, message) { var good = constraintApplied ? condition : !condition;
message =
(constraintApplied ? "with" : "without") + " constraint: should " +
(constraintApplied ? "" : "not ") +
message + " = " +
(good ? "OK" : "waiting...");
info(message); 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();
} returnnew 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));
} returnnew Promise(r => (resolve = r));
}
function isSilence(audioData) { var silence = true; for (var i = 0; i < audioData.length; ++i) { if (audioData[i] !== 128) {
silence = false;
}
} return silence;
}
function checkAudio(constraintApplied, stream) { var audio = mkElement("audio");
audio.srcObject = stream;
audio.play();
var context = new AudioContext(); var source = context.createMediaStreamSource(stream); var analyser = context.createAnalyser();
source.connect(analyser);
analyser.connect(context.destination);
return periodicCheck(() => { var sampleCount = analyser.frequencyBinCount;
info("got some audio samples: " + sampleCount); var buffer = new Uint8Array(sampleCount);
analyser.getByteTimeDomainData(buffer);
function checkVideo(constraintApplied, stream) { var video = mkElement("video");
video.srcObject = stream;
video.play();
return periodicCheck(() => { try { var canvas = mkElement("canvas"); var ctx = canvas.getContext("2d"); // Have to guard drawImage with the try as well, due to bug 879717. If // we get an error, this round fails, but that failure is usually just // transitory.
ctx.drawImage(video, 0, 0);
ctx.getImageData(0, 0, 1, 1); return check(
constraintApplied, false, "throw on getImageData for video"
);
} catch (e) { return check(
constraintApplied,
e.name === "SecurityError", "get a security error: " + e.name
);
}
}).then(() => {
video.pause();
ok(true, "video is " + (constraintApplied ? "" : "not ") + "protected");
});
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.