From 6bf0a5cb5034a7e684dcc3500e841785237ce2dd Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 19:32:43 +0200 Subject: Adding upstream version 1:115.7.0. Signed-off-by: Daniel Baumann --- .../browser_forgetAPI_EME_forgetThisSite.js | 259 +++++++++++++++++++++ 1 file changed, 259 insertions(+) create mode 100644 browser/components/contextualidentity/test/browser/browser_forgetAPI_EME_forgetThisSite.js (limited to 'browser/components/contextualidentity/test/browser/browser_forgetAPI_EME_forgetThisSite.js') diff --git a/browser/components/contextualidentity/test/browser/browser_forgetAPI_EME_forgetThisSite.js b/browser/components/contextualidentity/test/browser/browser_forgetAPI_EME_forgetThisSite.js new file mode 100644 index 0000000000..d36e47d3cb --- /dev/null +++ b/browser/components/contextualidentity/test/browser/browser_forgetAPI_EME_forgetThisSite.js @@ -0,0 +1,259 @@ +/* + * Bug 1278037 - A Test case for checking whether forgetting APIs are working for the media key. + */ + +const CC = Components.Constructor; + +const TEST_HOST = "example.com"; +const TEST_URL = + "http://" + + TEST_HOST + + "/browser/browser/components/contextualidentity/test/browser/"; + +const USER_CONTEXTS = ["default", "personal"]; + +const TEST_EME_KEY = { + initDataType: "keyids", + initData: '{"kids":["LwVHf8JLtPrv2GUXFW2v_A"], "type":"persistent-license"}', + kid: "LwVHf8JLtPrv2GUXFW2v_A", + key: "97b9ddc459c8d5ff23c1f2754c95abe8", + sessionType: "persistent-license", +}; + +// +// Support functions. +// + +async function openTabInUserContext(uri, userContextId) { + // Open the tab in the correct userContextId. + let tab = BrowserTestUtils.addTab(gBrowser, uri, { userContextId }); + + // Select tab and make sure its browser is focused. + gBrowser.selectedTab = tab; + tab.ownerGlobal.focus(); + + let browser = gBrowser.getBrowserForTab(tab); + await BrowserTestUtils.browserLoaded(browser); + return { tab, browser }; +} + +function HexToBase64(hex) { + var bin = ""; + for (var i = 0; i < hex.length; i += 2) { + bin += String.fromCharCode(parseInt(hex.substr(i, 2), 16)); + } + return window + .btoa(bin) + .replace(/=/g, "") + .replace(/\+/g, "-") + .replace(/\//g, "_"); +} + +function Base64ToHex(str) { + var bin = window.atob(str.replace(/-/g, "+").replace(/_/g, "/")); + var res = ""; + for (var i = 0; i < bin.length; i++) { + res += ("0" + bin.charCodeAt(i).toString(16)).substr(-2); + } + return res; +} + +function ByteArrayToHex(array) { + let bin = String.fromCharCode.apply(null, new Uint8Array(array)); + let res = ""; + + for (let i = 0; i < bin.length; i++) { + res += ("0" + bin.charCodeAt(i).toString(16)).substr(-2); + } + + return res; +} + +function generateKeyObject(aKid, aKey) { + let keyObj = { + kty: "oct", + kid: aKid, + k: HexToBase64(aKey), + }; + + return new TextEncoder().encode( + JSON.stringify({ + keys: [keyObj], + }) + ); +} + +function generateKeyInfo(aData) { + let keyInfo = { + initDataType: aData.initDataType, + initData: new TextEncoder().encode(aData.initData), + sessionType: aData.sessionType, + keyObj: generateKeyObject(aData.kid, aData.key), + }; + + return keyInfo; +} + +// Setup a EME key for the given browser, and return the sessionId. +async function setupEMEKey(browser) { + // Generate the key info. + let keyInfo = generateKeyInfo(TEST_EME_KEY); + + // Setup the EME key. + let result = await SpecialPowers.spawn( + browser, + [keyInfo], + async function (aKeyInfo) { + let access = await content.navigator.requestMediaKeySystemAccess( + "org.w3.clearkey", + [ + { + initDataTypes: [aKeyInfo.initDataType], + videoCapabilities: [{ contentType: "video/webm" }], + sessionTypes: ["persistent-license"], + persistentState: "required", + }, + ] + ); + let mediaKeys = await access.createMediaKeys(); + let session = mediaKeys.createSession(aKeyInfo.sessionType); + let res = {}; + + // Insert the EME key. + await new Promise(resolve => { + session.addEventListener("message", function (event) { + session + .update(aKeyInfo.keyObj) + .then(() => { + resolve(); + }) + .catch(() => { + ok(false, "Update the EME key fail."); + resolve(); + }); + }); + + session.generateRequest(aKeyInfo.initDataType, aKeyInfo.initData); + }); + + let map = session.keyStatuses; + + is(map.size, 1, "One EME key has been added."); + + if (map.size === 1) { + res.keyId = map.keys().next().value; + res.sessionId = session.sessionId; + } + + // Close the session. + session.close(); + await session.closed; + + return res; + } + ); + + // Check the EME key ID. + is( + ByteArrayToHex(result.keyId), + Base64ToHex(TEST_EME_KEY.kid), + "The key Id is correct." + ); + return result.sessionId; +} + +// Check whether the EME key has been cleared. +async function checkEMEKey(browser, emeSessionId) { + // Generate the key info. + let keyInfo = generateKeyInfo(TEST_EME_KEY); + keyInfo.sessionId = emeSessionId; + + await SpecialPowers.spawn(browser, [keyInfo], async function (aKeyInfo) { + let access = await content.navigator.requestMediaKeySystemAccess( + "org.w3.clearkey", + [ + { + initDataTypes: [aKeyInfo.initDataType], + videoCapabilities: [{ contentType: "video/webm" }], + sessionTypes: ["persistent-license"], + persistentState: "required", + }, + ] + ); + let mediaKeys = await access.createMediaKeys(); + let session = mediaKeys.createSession(aKeyInfo.sessionType); + + // First, load the session with the sessionId. + await session.load(aKeyInfo.sessionId); + + let map = session.keyStatuses; + + // Check that there is no media key here. + is( + map.size, + 0, + "No media key should be here after forgetThisSite() was called." + ); + }); +} + +// +// Test functions. +// + +add_setup(async function () { + // Make sure userContext is enabled. + await SpecialPowers.pushPrefEnv({ + set: [ + ["privacy.userContext.enabled", true], + ["media.mediasource.enabled", true], + ["media.mediasource.webm.enabled", true], + ["media.clearkey.persistent-license.enabled", true], + ], + }); +}); + +add_task(async function test_EME_forgetThisSite() { + let tabs = []; + let emeSessionIds = []; + + for (let userContextId of Object.keys(USER_CONTEXTS)) { + // Open our tab in the given user context. + tabs[userContextId] = await openTabInUserContext( + TEST_URL + "empty_file.html", + userContextId + ); + + // Setup EME Key. + emeSessionIds[userContextId] = await setupEMEKey( + tabs[userContextId].browser + ); + + // Close this tab. + BrowserTestUtils.removeTab(tabs[userContextId].tab); + } + + // Clear all EME data for a given domain with originAttributes pattern. + let mps = Cc["@mozilla.org/gecko-media-plugin-service;1"].getService( + Ci.mozIGeckoMediaPluginChromeService + ); + mps.forgetThisSite(TEST_HOST, JSON.stringify({})); + + // Open tabs again to check EME keys have been cleared. + for (let userContextId of Object.keys(USER_CONTEXTS)) { + // Open our tab in the given user context. + tabs[userContextId] = await openTabInUserContext( + TEST_URL + "empty_file.html", + userContextId + ); + + // Check whether EME Key has been cleared. + await checkEMEKey( + tabs[userContextId].browser, + emeSessionIds[userContextId] + ); + + // Close this tab. + BrowserTestUtils.removeTab(tabs[userContextId].tab); + } +}); -- cgit v1.2.3