Bug 1963188 - part4 : add test for WindowsMediaFoundationCDMOriginsListService. r=media-playback-reviewers,padenot,dom-storage-reviewers,janv

Also fixed the test failure for test_open_and_databases.js.

Differential Revision: https://phabricator.services.mozilla.com/D247368
This commit is contained in:
alwu
2025-05-08 18:41:06 +00:00
committed by alwu@mozilla.com
parent 67b6465752
commit 7d95097ca5
3 changed files with 222 additions and 3 deletions

View File

@@ -5,6 +5,29 @@
/* exported testSteps */
async function testSteps() {
const factory = (function () {
if (typeof Cc === "undefined") {
return indexedDB;
}
// In xpcshell tests (where `Cc` is defined), we avoid using the system
// principal because background services may create indexedDB databases
// concurrently under that principal. To prevent interference and ensure
// test isolation, we use a sandbox with a content principal instead.
const { PrincipalUtils } = ChromeUtils.importESModule(
"resource://testing-common/dom/quota/test/modules/PrincipalUtils.sys.mjs"
);
const principal = PrincipalUtils.createPrincipal("https://example.com");
const sandbox = new Cu.Sandbox(principal, {
wantGlobalProperties: ["indexedDB"],
});
return Cu.evalInSandbox("indexedDB", sandbox);
})();
const openInfos = [
{ name: "foo-a", version: 1 },
{ name: "foo-b", version: 1 },
@@ -15,7 +38,7 @@ async function testSteps() {
for (let index = 0; index < openInfos.length; index++) {
const openInfo = openInfos[index];
const request = indexedDB.open(openInfo.name, openInfo.version);
const request = factory.open(openInfo.name, openInfo.version);
await expectingUpgrade(request);
@@ -28,7 +51,7 @@ async function testSteps() {
info("Getting databases");
const databasesPromise = indexedDB.databases();
const databasesPromise = factory.databases();
info("Opening databases");
@@ -37,7 +60,7 @@ async function testSteps() {
for (let index = 0; index < openInfos.length; index++) {
const openInfo = openInfos[index];
const request = indexedDB.open(openInfo.name, openInfo.version);
const request = factory.open(openInfo.name, openInfo.version);
const promise = expectingSuccess(request);

View File

@@ -0,0 +1,6 @@
[DEFAULT]
subsuite = "media-bc"
tags = "media-engine-compatible"
skip-if = ["!wmfme"]
["browser_windowsMediaFoundationCDMOriginsListService.js"]

View File

@@ -0,0 +1,190 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/* global add_task */
"use strict";
/**
* This test verifies that nsIWindowsMediaFoundationCDMOriginsListService
* correctly triggers its callback and that the origin entries are propagated
* as expected. It also checks that the result of calling
* requestMediaKeySystemAccess for PlayReady is influenced by these entries.
*/
ChromeUtils.defineESModuleGetters(this, {
RemoteSettings: "resource://services-settings/remote-settings.sys.mjs",
BrowserTestUtils: "resource://testing-common/BrowserTestUtils.sys.mjs",
TestUtils: "resource://testing-common/TestUtils.sys.mjs",
});
const COLLECTION_NAME = "mfcdm-origins-list";
const gRemoteSettings = RemoteSettings(COLLECTION_NAME);
const gOriginsListService = Cc[
"@mozilla.org/media/wmfcdm-origins-list;1"
].getService(Ci.nsIWindowsMediaFoundationCDMOriginsListService);
const gEntries = [
{
origin: "example.com",
allowed: false,
},
{
origin: "example.org",
allowed: true,
},
];
add_task(async function testOriginsListServiceCallback() {
info(`Simulate sending initial entries update to RemoteSettings`);
await updateRemoteSettings(gEntries);
info(`Waiting for the callback to be triggered`);
let waitUpdate = TestUtils.topicObserved("updated-entries");
let callback = {
onOriginsListLoaded(entries) {
Assert.equal(entries.length, gEntries.length, "Entry count matches");
for (let expected of gEntries) {
let found = false;
for (let i = 0; i < entries.length; i++) {
let e = entries.queryElementAt(i, Ci.nsIOriginStatusEntry);
if (
e.origin === expected.origin &&
e.status === (expected.allowed ? 1 : 0)
) {
found = true;
break;
}
}
Assert.ok(
found,
`Expected origin (${expected.origin}/${expected.allowed}) found`
);
}
Services.obs.notifyObservers(null, "updated-entries");
},
};
gOriginsListService.setCallback(callback);
await waitUpdate;
info(
`Simulate adding another new record which should trigger callback again`
);
waitUpdate = TestUtils.topicObserved("updated-entries");
gEntries.push({
origin: "example.net",
allowed: false,
});
await Promise.all([
TestUtils.topicObserved("updated-entries"),
updateRemoteSettings(gEntries),
]);
info(
`Remove old callback, and set a new callback, which should be triggered as well`
);
waitUpdate = TestUtils.topicObserved("updated-entries");
gOriginsListService.removeCallback(callback);
gOriginsListService.setCallback(callback);
await waitUpdate;
});
// This task follows the entries set in the previous task.
add_task(async function testCheckCreateKeySystemAccess() {
info(`Set pre-requirement prefs`);
await SpecialPowers.pushPrefEnv({
set: [
["media.wmf.media-engine.enabled", 2],
// Our mock CDM doesn't implement 'IsTypeSupportedEx()', only 'IsTypeSupported()'
["media.eme.playready.istypesupportedex", false],
["media.eme.wmf.use-mock-cdm-for-external-cdms", true],
],
});
info(`Open a new tab and navigate`);
let tab = await BrowserTestUtils.openNewForegroundTab(window.gBrowser);
// Test both preference values to control the default behavior when an origin
// is not explicitly listed in the entries.
// 3 : enabled allowed by default via Remote Settings
// 4 : enabled blocked by default via Remote Settings
const originFilterPrefs = [3, 4];
for (let prefValue of originFilterPrefs) {
const isDefaultAllowed = prefValue == 3;
info(`Testing default behavior: ${isDefaultAllowed ? "allow" : "block"}`);
await SpecialPowers.pushPrefEnv({
set: [["media.eme.mfcdm.origin-filter.enabled", prefValue]],
});
const notSpecifiedDomains = [
// Sub-domain, should follow the main domain result
{
origin: "test1.example.com",
allowed: false,
},
{
origin: "test1.example.org",
allowed: true,
},
// Not specified and not a subdomain, follow the default result
{
origin: "example.onion",
allowed: isDefaultAllowed,
},
];
for (let entry of gEntries.concat(notSpecifiedDomains)) {
info(`Navigate to ${entry.origin}`);
BrowserTestUtils.startLoadingURIString(tab.linkedBrowser, entry.origin);
await BrowserTestUtils.browserLoaded(tab.linkedBrowser);
info(`Creating a key system access, which should be ${entry.allowed}`);
await checkCreateKeySystemAccess({
tab,
isAllowed: entry.allowed,
});
}
}
info(`Remove tab`);
await BrowserTestUtils.removeTab(tab);
});
// Below are helper functions
function updateRemoteSettings(entries) {
return gRemoteSettings.emit("sync", {
data: {
current: entries,
created: [],
updated: [],
deleted: [],
},
});
}
function checkCreateKeySystemAccess({ tab, isAllowed } = {}) {
return SpecialPowers.spawn(
tab.linkedBrowser,
[isAllowed],
async isAllowed_ => {
const keySystem = "com.microsoft.playready.recommendation";
const config = [
{
videoCapabilities: [
{
contentType: 'video/mp4; codecs="avc1.42E01E"',
},
],
initDataTypes: ["cenc"],
sessionTypes: ["temporary"],
},
];
try {
info("Attemping to create a key system access");
await content.navigator.requestMediaKeySystemAccess(keySystem, config);
ok(isAllowed_, "Created a key system access");
} catch (e) {
ok(!isAllowed_, "Not allowed to create a key system access");
}
}
);
}