Source code

Revision control

Copy as Markdown

Other Tools

Test Info:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<script type="application/javascript" src="mediaStreamPlayback.js"></script>
</head>
<body>
<script type="application/javascript">
"use strict";
createHTML({
title: "ondevicechange test with privacy.resistFingerprinting",
bug: "1811836",
});
async function resolveOnEvent(target, name) {
return new Promise(r =>
target.addEventListener(name, r, { once: true })
);
}
let eventCount = 0;
async function triggerVideoDevicechange() {
++eventCount;
// "media.getusermedia.fake-camera-name" specifies the name of the single
// fake video camera.
// Changing the pref imitates replacing one device with another.
return pushPrefs([
"media.getusermedia.fake-camera-name",
`devicechange ${eventCount}`,
]);
}
runTest(async () => {
const basePrefs = [
// Use the fake video backend to trigger devicechange events.
["media.navigator.streams.fake", true],
// Loopback would override fake.
["media.video_loopback_dev", ""],
// Make fake devices count as real, permission-wise, or devicechange
// events won't be exposed
["media.navigator.permission.fake", true],
// For gUM.
["media.navigator.permission.disabled", true],
];
await withPrefs(
[
...basePrefs,
// Enable privacy.resistFingerprinting to test the prevention of
// device list changes.
["privacy.resistFingerprinting", true],
],
async () => {
const topDevices = navigator.mediaDevices;
const topEventPromise1 = resolveOnEvent(topDevices, "devicechange");
(await topDevices.getUserMedia({ video: true }))
.getTracks()[0]
.stop();
await triggerVideoDevicechange(); // Pop pref list after this.
const racer = {};
is(
await Promise.race([topEventPromise1, racer]),
racer,
"devicechange event is NOT fired in top window for replaced device when " +
"privacy.resistFingerprinting is enabled"
);
await SpecialPowers.popPrefEnv();
}
);
await withPrefs(
[
...basePrefs,
// Disable privacy.resistFingerprinting to test the exposure of device list
// changes.
["privacy.resistFingerprinting", false],
],
async () => {
const topDevices = navigator.mediaDevices;
const topEventPromise2 = resolveOnEvent(topDevices, "devicechange");
await triggerVideoDevicechange();
await topEventPromise2;
ok(
true,
"devicechange event is fired in top window for replaced device when " +
"privacy.resistFingerprinting is disabled"
);
await SpecialPowers.popPrefEnv();
}
);
});
</script>
</body>
</html>