DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Mercurial (c68fe15a81fc)

VCS Links

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212
<!DOCTYPE HTML>
<html>
<head>
  <title>Test Encrypted Media Extensions access can be gated by application</title>
  <script src="/tests/SimpleTest/SimpleTest.js"></script>
  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
  <script type="text/javascript" src="manifest.js"></script>
  <script type="text/javascript" src="eme.js"></script>
</head>
<body>
<pre id="test">
<script class="testbody" type="text/javascript">

// These test cases should be used to make a request to
// requestMediaKeySystemAccess and have the following members:
// name: a name describing the test.
// askAppApproval: used to set prefs such so that Gecko will ask for app
// approval for EME if true, or not if false.
// appApproves: used to set prefs to simulate app approval of permission
// request, true if the app approves the request, false if not.
// expectedKeySystemAccess: true if we expect to be granted key system access,
// false if not.
const testCases = [
  {
    name: "Don't check for app approval",
    askAppApproval: false,
    expectedKeySystemAccess: true,
  },
  {
    name: "Check for app approval and app denies request",
    askAppApproval: true,
    appApproves: false,
    expectedKeySystemAccess: false,
  },
  {
    name: "Check for app approval and app allows request",
    askAppApproval: true,
    appApproves: true,
    expectedKeySystemAccess: true,
  },
];

// Options for requestMediaKeySystemAccess that are expected to work.
const options = [{
  initDataTypes: ['webm'],
  audioCapabilities: [
    { contentType: 'audio/webm; codecs="opus"' },
  ],
  videoCapabilities: [
    { contentType: 'video/webm; codecs="vp8"' }
  ]
}];

async function setTestPrefs({askAppApproval, appApproves}) {
  if (!askAppApproval) {
    // Test doesn't want app approval, set pref so we don't ask and unset prefs
    // used to determine permission response as we don't need them.
    await SpecialPowers.pushPrefEnv({
      set: [["media.eme.require-app-approval", false]],
      clear: [
        ["media.eme.require-app-approval.prompt.testing"],
        ["media.eme.require-app-approval.prompt.testing.allow"],
      ]
    });
    return;
  }

  // Test wants app approval, and will approve deny requests per appApproces
  // value, set prefs accordingly.
  await SpecialPowers.pushPrefEnv({
    set: [
      ["media.eme.require-app-approval", true],
      ["media.eme.require-app-approval.prompt.testing", true],
      ["media.eme.require-app-approval.prompt.testing.allow", appApproves],
    ],
  });
}

// Run a test case that makes a single requestMediaKeySystemAccess call. The
// outcome of such a test run should depend on the test case's setting of
// preferences controlling the eme app approval.
async function testSingleRequest(testCase) {
  await setTestPrefs(testCase);

  try {
    await navigator.requestMediaKeySystemAccess(CLEARKEY_KEYSYSTEM, options);
    ok(testCase.expectedKeySystemAccess,
       `testSingleRequest ${testCase.name}: allowed media key system access.`);
  } catch(e) {
    is(e.name,
       "NotSupportedError",
       "Should get NotSupportedError when request is blocked.");
    is(e.message,
       "The application embedding this user agent has blocked MediaKeySystemAccess",
       "Should get blocked error message.");
    ok(!testCase.expectedKeySystemAccess,
       `testSingleRequest ${testCase.name}: denied media key system access.`);
  }
}

// Run a test case that, but using invalid arguments for
// requestMediaKeySystemAccess. Because we expect the args to be checked
// before requesting app approval, this test ensures that we always fail when
// using bad args, regardless of the app approval prefs set.
async function testRequestWithInvalidArgs(testCase) {
  const badOptions = [{
    initDataTypes: ['badType'],
    audioCapabilities: [
      { contentType: 'audio/webm; codecs="notACodec"' },
    ],
    videoCapabilities: [
      { contentType: 'video/webm; codecs="notACodec"' }
    ]
  }];

  await setTestPrefs(testCase);

  // Check that calls with a bad key system fail.
  try {
    await navigator.requestMediaKeySystemAccess("BadKeySystem", options);
    ok(false,
       `testRequestWithInvalidArgs ${testCase.name}: should not get access when using bad key system.`);
  } catch(e) {
    is(e.name,
       "NotSupportedError",
       "Should get NotSupportedError using bad key system.");
    is(e.message,
       "Key system is unsupported",
       "Should get not supported key system error message.");
  }

  // Check that calls with the bad options fail.
  try {
    await navigator.requestMediaKeySystemAccess(CLEARKEY_KEYSYSTEM, badOptions);
    ok(false,
       `testRequestWithInvalidArgs ${testCase.name}: should not get access when using bad options.`);
  } catch(e) {
    is(e.name,
       "NotSupportedError",
       "Should get NotSupportedError using bad options.");
    is(e.message,
       "Key system configuration is not supported",
       "Should get not supported config error message.");
  }
}

// Run a test case and make multiple requests with the same case. Check that
// all requests are resolved with the expected outcome.
async function testMultipleRequests(testCase) {
  // Number of requests to concurrently make.
  const NUM_REQUESTS = 5;

  await setTestPrefs(testCase);

  let resolveHandler = () => {
    ok(testCase.expectedKeySystemAccess,
       `testMultipleRequests ${testCase.name}: allowed media key system access.`);
  }

  let rejectHandler = e => {
    is(e.name,
       "NotSupportedError",
       "Should get NotSupportedError when request is blocked.");
    is(e.message,
       "The application embedding this user agent has blocked MediaKeySystemAccess",
       "Should get blocked error message.");
    ok(!testCase.expectedKeySystemAccess,
       `testMultipleRequests ${testCase.name}: denied media key system access.`);
  }

  let accessPromises = [];
  for(let i = 0; i < NUM_REQUESTS; i++) {
    // Request access then chain to our resolve and reject handlers. The
    // handlers assert test state then resolve the promise chain. Ensuring the
    // chain is always resolved allows us to correctly await all outstanding
    // requests -- otherwise rejects short circuit the Promise.all call below.
    let accessPromise = navigator.requestMediaKeySystemAccess(CLEARKEY_KEYSYSTEM, options)
      .then(resolveHandler, rejectHandler);
    accessPromises.push(accessPromise);
  }
  // Wait for all promises to be resolved. If not, we'll time out. Because
  // our reject handler chains back into a resolved promise, this should wait
  // for all requests to be serviced, even when requestMediaKeySystemAccess's
  // promise is rejected.
  await Promise.all(accessPromises);
}

async function beginTest() {
  // The tests rely on prefs being set, so run them in sequence. If we run in
  // parallel the tests break each other by overriding prefs.
  for (const testCase of testCases) {
    await testSingleRequest(testCase);
  }
  for (const testCase of testCases) {
    await testRequestWithInvalidArgs(testCase);
  }
  for (const testCase of testCases) {
    await testMultipleRequests(testCase);
  }
  SimpleTest.finish();
}

if (!IsMacOSSnowLeopardOrEarlier()) {
  SimpleTest.waitForExplicitFinish();
  SetupEMEPref(beginTest);
} else {
  todo(false, "Test disabled on this platform.");
}
</script>
</pre>
</body>
</html>