iframe_sensor_handler.html (3225B)
1 <!DOCTYPE html> 2 <meta charset="utf-8"> 3 <title>cross-origin iframe sensor tester</title> 4 <script src="/resources/testdriver.js?feature=bidi"></script> 5 <script src="/resources/testdriver-vendor.js"></script> 6 <script src="/generic-sensor/resources/generic-sensor-helpers.js"></script> 7 <script> 8 let sensor = null; 9 10 test_driver.set_test_context(window.parent); 11 12 // This function is defined separately so that it is added only once 13 // regardless of how many times the 'start_sensor' command is received. 14 function sensorReadingEventHandler() { 15 window.parent.postMessage( 16 { 17 eventName: 'reading', 18 serializedSensor: serialize_sensor_data(sensor), 19 }, '*'); 20 } 21 22 async function messageHandler(e) { 23 switch (e.data.command) { 24 case 'create_sensor': 25 if (!sensor) { 26 const { sensorName, permissionName } = e.data.sensorData; 27 // TODO(https://github.com/w3c/permissions/issues/419): This does not 28 // work as expected: due to the set_test_context() call above, this 29 // call goes through the top-level frame, which has a different 30 // origin in cross-origin tests, meaning that cross-origin tests only 31 // really work when permissions are granted by default. This can only 32 // be fixed by testdriver.js allowing set_permission() to specify a 33 // different origin. 34 await test_driver.bidi.permissions.set_permission( 35 {descriptor: {name: permissionName}, state: 'granted'}); 36 sensor = new self[sensorName](); 37 } 38 return Promise.resolve(); 39 40 case 'start_sensor': 41 return new Promise((resolve, reject) => { 42 // This event listener is different from the ones below, as it is 43 // supposed to be used together with IframeSensorReadingEventWatcher. 44 // It sends a message whenever there is an event, and window.parent 45 // decides whether it was expected or not. It is the only way to have 46 // something akin to EventWatcher in a cross-origin iframe. 47 sensor.addEventListener('reading', sensorReadingEventHandler); 48 49 sensor.addEventListener('activate', () => { 50 resolve(); 51 }, { once: true }); 52 sensor.addEventListener('error', e => { 53 reject(`${e.error.name}: ${e.error.message}`); 54 }, { once: true }); 55 sensor.start(); 56 }); 57 58 case 'has_reading': 59 return Promise.resolve(sensor.hasReading); 60 61 case 'stop_sensor': 62 if (sensor) { 63 sensor.stop(); 64 } 65 return Promise.resolve(); 66 67 default: 68 return Promise.reject(`unknown command "${e.data.command}"`); 69 } 70 } 71 72 window.onmessage = async (e) => { 73 // The call to test_driver.set_context() above makes messages other than 74 // those we are specifically waiting for to be delivered too. Ignore those 75 // here. 76 if (!e.data.command) { 77 return; 78 } 79 80 try { 81 test_driver.message_test({ 82 command: e.data.command, 83 result: await messageHandler(e), 84 }); 85 } catch (error) { 86 test_driver.message_test({ 87 command: e.data.command, 88 error, 89 }); 90 } 91 } 92 </script>