test_eme_requestMediaKeySystemAccess_with_app_approval.html (7162B)
1 <!DOCTYPE HTML> 2 <html> 3 <head> 4 <title>Test Encrypted Media Extensions access can be gated by application</title> 5 <script src="/tests/SimpleTest/SimpleTest.js"></script> 6 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> 7 <script type="text/javascript" src="manifest.js"></script> 8 <script type="text/javascript" src="eme.js"></script> 9 </head> 10 <body> 11 <pre id="test"> 12 <script class="testbody" type="text/javascript"> 13 14 // These test cases should be used to make a request to 15 // requestMediaKeySystemAccess and have the following members: 16 // name: a name describing the test. 17 // askAppApproval: used to set prefs such so that Gecko will ask for app 18 // approval for EME if true, or not if false. 19 // appApproves: used to set prefs to simulate app approval of permission 20 // request, true if the app approves the request, false if not. 21 // expectedKeySystemAccess: true if we expect to be granted key system access, 22 // false if not. 23 const testCases = [ 24 { 25 name: "Don't check for app approval", 26 askAppApproval: false, 27 expectedKeySystemAccess: true, 28 }, 29 { 30 name: "Check for app approval and app denies request", 31 askAppApproval: true, 32 appApproves: false, 33 expectedKeySystemAccess: false, 34 }, 35 { 36 name: "Check for app approval and app allows request", 37 askAppApproval: true, 38 appApproves: true, 39 expectedKeySystemAccess: true, 40 }, 41 ]; 42 43 // Options for requestMediaKeySystemAccess that are expected to work. 44 const options = [{ 45 initDataTypes: ['webm'], 46 audioCapabilities: [ 47 { contentType: 'audio/webm; codecs="opus"' }, 48 ], 49 videoCapabilities: [ 50 { contentType: 'video/webm; codecs="vp8"' } 51 ] 52 }]; 53 54 async function setTestPrefs({askAppApproval, appApproves}) { 55 if (!askAppApproval) { 56 // Test doesn't want app approval, set pref so we don't ask and unset prefs 57 // used to determine permission response as we don't need them. 58 await SpecialPowers.pushPrefEnv({ 59 set: [["media.eme.require-app-approval", false]], 60 clear: [ 61 ["media.eme.require-app-approval.prompt.testing"], 62 ["media.eme.require-app-approval.prompt.testing.allow"], 63 ] 64 }); 65 return; 66 } 67 68 // Test wants app approval, and will approve deny requests per appApproces 69 // value, set prefs accordingly. 70 await SpecialPowers.pushPrefEnv({ 71 set: [ 72 ["media.eme.require-app-approval", true], 73 ["media.eme.require-app-approval.prompt.testing", true], 74 ["media.eme.require-app-approval.prompt.testing.allow", appApproves], 75 ], 76 }); 77 } 78 79 // Run a test case that makes a single requestMediaKeySystemAccess call. The 80 // outcome of such a test run should depend on the test case's setting of 81 // preferences controlling the eme app approval. 82 async function testSingleRequest(testCase) { 83 await setTestPrefs(testCase); 84 85 try { 86 await navigator.requestMediaKeySystemAccess(CLEARKEY_KEYSYSTEM, options); 87 ok(testCase.expectedKeySystemAccess, 88 `testSingleRequest ${testCase.name}: allowed media key system access.`); 89 } catch(e) { 90 is(e.name, 91 "NotSupportedError", 92 "Should get NotSupportedError when request is blocked."); 93 is(e.message, 94 "The application embedding this user agent has blocked MediaKeySystemAccess", 95 "Should get blocked error message."); 96 ok(!testCase.expectedKeySystemAccess, 97 `testSingleRequest ${testCase.name}: denied media key system access.`); 98 } 99 } 100 101 // Run a test case that, but using invalid arguments for 102 // requestMediaKeySystemAccess. Because we expect the args to be checked 103 // before requesting app approval, this test ensures that we always fail when 104 // using bad args, regardless of the app approval prefs set. 105 async function testRequestWithInvalidArgs(testCase) { 106 const badOptions = [{ 107 initDataTypes: ['badType'], 108 audioCapabilities: [ 109 { contentType: 'audio/webm; codecs="notACodec"' }, 110 ], 111 videoCapabilities: [ 112 { contentType: 'video/webm; codecs="notACodec"' } 113 ] 114 }]; 115 116 await setTestPrefs(testCase); 117 118 // Check that calls with a bad key system fail. 119 try { 120 await navigator.requestMediaKeySystemAccess("BadKeySystem", options); 121 ok(false, 122 `testRequestWithInvalidArgs ${testCase.name}: should not get access when using bad key system.`); 123 } catch(e) { 124 is(e.name, 125 "NotSupportedError", 126 "Should get NotSupportedError using bad key system."); 127 is(e.message, 128 "Key system is unsupported", 129 "Should get not supported key system error message."); 130 } 131 132 // Check that calls with the bad options fail. 133 try { 134 await navigator.requestMediaKeySystemAccess(CLEARKEY_KEYSYSTEM, badOptions); 135 ok(false, 136 `testRequestWithInvalidArgs ${testCase.name}: should not get access when using bad options.`); 137 } catch(e) { 138 is(e.name, 139 "NotSupportedError", 140 "Should get NotSupportedError using bad options."); 141 is(e.message, 142 "Key system configuration is not supported", 143 "Should get not supported config error message."); 144 } 145 } 146 147 // Run a test case and make multiple requests with the same case. Check that 148 // all requests are resolved with the expected outcome. 149 async function testMultipleRequests(testCase) { 150 // Number of requests to concurrently make. 151 const NUM_REQUESTS = 5; 152 153 await setTestPrefs(testCase); 154 155 let resolveHandler = () => { 156 ok(testCase.expectedKeySystemAccess, 157 `testMultipleRequests ${testCase.name}: allowed media key system access.`); 158 } 159 160 let rejectHandler = e => { 161 is(e.name, 162 "NotSupportedError", 163 "Should get NotSupportedError when request is blocked."); 164 is(e.message, 165 "The application embedding this user agent has blocked MediaKeySystemAccess", 166 "Should get blocked error message."); 167 ok(!testCase.expectedKeySystemAccess, 168 `testMultipleRequests ${testCase.name}: denied media key system access.`); 169 } 170 171 let accessPromises = []; 172 for(let i = 0; i < NUM_REQUESTS; i++) { 173 // Request access then chain to our resolve and reject handlers. The 174 // handlers assert test state then resolve the promise chain. Ensuring the 175 // chain is always resolved allows us to correctly await all outstanding 176 // requests -- otherwise rejects short circuit the Promise.all call below. 177 let accessPromise = navigator.requestMediaKeySystemAccess(CLEARKEY_KEYSYSTEM, options) 178 .then(resolveHandler, rejectHandler); 179 accessPromises.push(accessPromise); 180 } 181 // Wait for all promises to be resolved. If not, we'll time out. Because 182 // our reject handler chains back into a resolved promise, this should wait 183 // for all requests to be serviced, even when requestMediaKeySystemAccess's 184 // promise is rejected. 185 await Promise.all(accessPromises); 186 } 187 188 // The tests rely on prefs being set, so run them in sequence. If we run in 189 // parallel the tests break each other by overriding prefs. 190 for (const testCase of testCases) { 191 add_task(() => testSingleRequest(testCase)); 192 } 193 for (const testCase of testCases) { 194 add_task(() => testRequestWithInvalidArgs(testCase)); 195 } 196 for (const testCase of testCases) { 197 add_task(() => testMultipleRequests(testCase)); 198 } 199 </script> 200 </pre> 201 </body> 202 </html>