test_autoplay_policy_web_audio_notResumePageInvokedSuspendedAudioContext.html (2833B)
1 <!DOCTYPE HTML> 2 <html> 3 <head> 4 <title>Autoplay policy test : do not resume AudioContext which is suspended by page</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 </head> 9 <body> 10 <script> 11 /* import-globals-from ../../../test/manifest.js */ 12 /** 13 * This test is used to ensure we won't resume AudioContext which is suspended 14 * by page (it means calling suspend() explicitly) when calling 15 * `AudioScheduledSourceNode.start()`. 16 */ 17 18 SimpleTest.waitForExplicitFinish(); 19 20 (async function testNotResumeUserInvokedSuspendedAudioContext() { 21 await setupTestPreferences(); 22 23 const nodeTypes = ["AudioBufferSourceNode", "ConstantSourceNode", "OscillatorNode"]; 24 for (let nodeType of nodeTypes) { 25 info(`- create an audio context which should not be allowed to start, it's allowed to be created, but it's forbidden to start -`); 26 await createAudioContext(); 27 28 info(`- explicitly suspend the AudioContext in the page -`); 29 suspendAudioContext(); 30 31 info(`- start an 'AudioScheduledSourceNode', and check that the AudioContext does not start, because it has been explicitly suspended -`); 32 await createAndStartAudioScheduledSourceNode(nodeType); 33 } 34 35 SimpleTest.finish(); 36 })(); 37 38 /** 39 * Test utility functions 40 */ 41 42 function setupTestPreferences() { 43 return SpecialPowers.pushPrefEnv({"set": [ 44 ["media.autoplay.default", SpecialPowers.Ci.nsIAutoplay.BLOCKED], 45 ["media.autoplay.blocking_policy", 0], 46 ["media.autoplay.block-event.enabled", true], 47 ]}); 48 } 49 50 async function createAudioContext() { 51 /* global ac */ 52 window.ac = new AudioContext(); 53 await once(ac, "blocked"); 54 is(ac.state, "suspended", `AudioContext is blocked.`); 55 } 56 57 function suspendAudioContext() { 58 try { 59 ac.suspend(); 60 } catch(e) { 61 ok(false, `AudioContext suspend failed!`); 62 } 63 } 64 65 async function createAndStartAudioScheduledSourceNode(nodeType) { 66 let node; 67 info(`- create ${nodeType} -`); 68 switch (nodeType) { 69 case "AudioBufferSourceNode": 70 node = ac.createBufferSource(); 71 break; 72 case "ConstantSourceNode": 73 node = ac.createConstantSource(); 74 break; 75 case "OscillatorNode": 76 node = ac.createOscillator(); 77 break; 78 default: 79 ok(false, "undefined AudioScheduledSourceNode type"); 80 return; 81 } 82 node.connect(ac.destination); 83 84 // activate the document in order to allow autoplay. 85 SpecialPowers.wrap(document).notifyUserGestureActivation(); 86 node.start(); 87 88 await once(ac, "blocked"); 89 is(ac.state, "suspended", `AudioContext should not be resumed.`); 90 91 // reset the activation flag of the document in order not to interfere next test. 92 SpecialPowers.wrap(document).clearUserGestureActivation(); 93 } 94 95 </script>