From 57fbbb2179141a672ee861ba53d9afb705bdb7f8 Mon Sep 17 00:00:00 2001 From: Raphael Kubo da Costa Date: Tue, 25 Jan 2022 03:24:26 -0800 Subject: [PATCH] sensors: Do nothing in Sensor.start() when the document is not fully active. When a sensor is created on e.g. an iframe that is later removed from its parent via removeChild(), we end up in a situation where a sensor instance did get created but which does not have a valid ExecutionContext by the time start() is invoked. Check for a valid ExecutionContext when start() is called and bail out early if it is null. https://github.com/w3c/sensors/issues/415 tracks handling non-fully active documents from a spec perspective; once that one is fixed we should probably throw an error in this case rather than silently doing nothing. Bug: 1289924 Change-Id: I2b033252d93347ba7c91385bdb510b69b8298aa2 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3412476 Reviewed-by: Reilly Grant Commit-Queue: Raphael Kubo Da Costa Cr-Commit-Position: refs/heads/main@{#962930} --- .../generic-sensor-iframe-tests.sub.js | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/generic-sensor/generic-sensor-iframe-tests.sub.js b/generic-sensor/generic-sensor-iframe-tests.sub.js index 11c9f50f4ab6f9..1d1a012380f638 100644 --- a/generic-sensor/generic-sensor-iframe-tests.sub.js +++ b/generic-sensor/generic-sensor-iframe-tests.sub.js @@ -155,4 +155,32 @@ function run_generic_sensor_iframe_tests(sensorName) { iframe.parentNode.removeChild(iframe); window.focus(); }, `${sensorName}: losing a document's frame with an active sensor does not crash`); + + sensor_test(async t => { + assert_implements(sensorName in self, `${sensorName} is not supported.`); + const iframe = document.createElement('iframe'); + iframe.allow = featurePolicies.join(';') + ';'; + iframe.src = 'https://{{host}}:{{ports[https][0]}}/generic-sensor/resources/iframe_sensor_handler.html'; + + // Create sensor in the iframe (we do not care whether this is a + // cross-origin nested context in this test). + const iframeLoadWatcher = new EventWatcher(t, iframe, 'load'); + document.body.appendChild(iframe); + await iframeLoadWatcher.wait_for('load'); + + // The purpose of this message is to initialize the mock backend in the + // iframe. We are not going to use the sensor created there. + await send_message_to_iframe(iframe, {command: 'create_sensor', + type: sensorName}); + + const iframeSensor = new iframe.contentWindow[sensorName](); + assert_not_equals(iframeSensor, null); + + // Remove iframe from main document. |iframeSensor| no longer has a + // non-null browsing context. Calling start() should probably throw an + // error when called from a non-fully active document, but that depends on + // https://github.com/w3c/sensors/issues/415 + iframe.parentNode.removeChild(iframe); + iframeSensor.start(); + }, `${sensorName}: calling start() in a non-fully active document does not crash`); }