summaryrefslogtreecommitdiffstats
path: root/browser/components/contextualidentity/test/browser/browser_forgetAPI_EME_forgetThisSite.js
diff options
context:
space:
mode:
Diffstat (limited to 'browser/components/contextualidentity/test/browser/browser_forgetAPI_EME_forgetThisSite.js')
-rw-r--r--browser/components/contextualidentity/test/browser/browser_forgetAPI_EME_forgetThisSite.js259
1 files changed, 259 insertions, 0 deletions
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);
+ }
+});