file_trigger_actionhandler_window.html (3506B)
1 <!DOCTYPE HTML> 2 <html> 3 <head> 4 <title>Test window for triggering media session's action handler</title> 5 <script src="/tests/SimpleTest/SimpleTest.js"></script> 6 <script src="MediaSessionTestUtils.js"></script> 7 </head> 8 <body> 9 <video id="testVideo" src="gizmo.mp4" loop></video> 10 <iframe id="childFrame"></iframe> 11 <script> 12 13 var triggeredActionNums = 0; 14 15 nextWindowMessage().then( 16 async (event) => { 17 const testInfo = event.data; 18 await createSession(testInfo); 19 // Media session would only become active if there is any media currently 20 // playing. Non-active media session won't receive any actions. Therefore, 21 // we start media playback before testing media session. 22 await startMediaPlayback(testInfo); 23 for (const action of gMediaSessionActions) { 24 await waitUntilActionHandlerTriggered(action, testInfo); 25 } 26 endTestAndReportResult(); 27 }); 28 29 /** 30 * The following are helper functions 31 */ 32 async function startMediaPlayback({shouldCreateFrom}) { 33 info(`wait until media starts playing`); 34 if (shouldCreateFrom == "main-frame") { 35 const video = document.getElementById("testVideo"); 36 await video.play(); 37 // As we can't observe `media-displayed-playback-changed` notification, 38 // that can only be observed in the chrome process. Therefore, we use a 39 // workaround instead which is to wait for a while to ensure that the 40 // controller has already been created in the chrome process. 41 let timeupdatecount = 0; 42 await new Promise(r => video.ontimeupdate = () => { 43 if (++timeupdatecount == 3) { 44 video.ontimeupdate = null; 45 r(); 46 } 47 }); 48 } else { 49 const iframe = document.getElementById("childFrame"); 50 iframe.contentWindow.postMessage("play", "*"); 51 await new Promise(r => { 52 window.onmessage = event => { 53 is(event.data, "played", `media started playing in child-frame`); 54 r(); 55 }; 56 }); 57 } 58 } 59 60 async function createSession({shouldCreateFrom, origin}) { 61 info(`create media session in ${shouldCreateFrom}`); 62 if (shouldCreateFrom == "main-frame") { 63 // Simply referencing media session will create media session. 64 navigator.mediaSession; 65 return; 66 }; 67 const frame = document.getElementById("childFrame"); 68 const originURL = origin == "same-origin" 69 ? "http://mochi.test:8888" : "http://example.org"; 70 frame.src = originURL + "/tests/dom/media/mediasession/test/file_trigger_actionhandler_frame.html"; 71 await new Promise(r => frame.onload = r); 72 } 73 74 async function waitUntilActionHandlerTriggered(action, {shouldCreateFrom}) { 75 info(`wait until '${action}' handler of media session created in ` + 76 `${shouldCreateFrom} is triggered`); 77 if (shouldCreateFrom == "main-frame") { 78 let promise = new Promise(resolve => { 79 navigator.mediaSession.setActionHandler(action, () => { 80 ok(true, `Triggered ${action} handler`); 81 triggeredActionNums++; 82 resolve(); 83 }); 84 }); 85 SpecialPowers.generateMediaControlKeyTestEvent(action); 86 await promise; 87 return; 88 } 89 SpecialPowers.generateMediaControlKeyTestEvent(action); 90 if ((await nextWindowMessage()).data == action) { 91 info(`Triggered ${action} handler in child-frame`); 92 triggeredActionNums++; 93 } 94 } 95 96 function endTestAndReportResult() { 97 const w = window.opener || window.parent; 98 if (triggeredActionNums == gMediaSessionActions.length) { 99 w.postMessage("success", "*"); 100 } else { 101 w.postMessage("fail", "*"); 102 } 103 } 104 105 </script> 106 </body> 107 </html>