Bug 269706
Summary: | DeviceOrientationEvent.requestPermission() fails when called from worker message | ||
---|---|---|---|
Product: | WebKit | Reporter: | Ashley Gullen <ashley> |
Component: | WebKit Misc. | Assignee: | Nobody <webkit-unassigned> |
Status: | NEW | ||
Severity: | Normal | CC: | cdumez, karlcow, marcosc, webkit-bug-importer |
Priority: | P2 | Keywords: | InRadar |
Version: | Safari 17 | ||
Hardware: | Unspecified | ||
OS: | Unspecified |
Ashley Gullen
In Safari on iOS, calling DeviceOrientationEvent.requestPermission() after a touch end event (in a user activation), but after a round-trip to a Web Worker and back via postMessage(), Safari denies the permission request. This ought to fall within the HTML standard user activation requirements, but it seems Safari does not support this in this case. It is blocking us shipping OffscreenCanvas in Safari for our engine Construct (www.construct.net). In that case we use an architecture where all input events are posted to the worker, all engine logic runs in the worker, and then it posts back to the DOM to make calls unavailable in the worker (e.g. DeviceOrientationEvent.requestPermission()). This is normally fast enough to still count as a user activation.
Repro: https://downloads.scirra.com/labs/safariorientation/
Steps to reproduce:
1. Load in Safari on iOS
2. Tap the screen
Expected result:
A permission prompt to appear; granting it to then show orientation data. This works in Chrome for Android.
Observed result:
No permission prompt appears; permission is shown as denied
Other remarks:
If I make a minimal repro, the problem does not seem to occur. It appears Safari has some non-standard heuristics for allowing the permission prompt in this case which don't work for our full engine. The same problem also applies to DeviceMotionEvent.requestPermission().
Please note I filed an issue about standards-compliant user gesture tracking in 2021 (issue 225559), and have twice requested it for the Interop projects (https://github.com/web-platform-tests/interop/issues/142, https://github.com/web-platform-tests/interop/issues/142), in both cases denied, and yet we keep running in to such problems. Some attention paid to making sure Safari handles user activation consistently would be much appreciated.
Attachments | ||
---|---|---|
Add attachment proposed patch, testcase, etc. |
Marcos Caceres
I can confirm that indeed, with a minimal case, it does prompt:
```
var b = document.createElement("button")
b.innerText = "THIS IS A BUTTON"
b.onclick = async () => {
try {
window.postMessage("this doesn't do anything", "*");
console.log("Requesting permission");
const result = await self["DeviceOrientationEvent"]["requestPermission"]();
console.log("Permission result", result);
} catch (e) {
console.error(e);
}
};
document.body.appendChild(b);
```
Ashley, does you code poke at any other of the APIs in parallel? One of the others might be consuming the user gesture.
Irrespective, looking at the code, it should be checking for transient activation (that's not the issue tho)... so we should fix that.
Marcos Caceres
*looking at the *WebKit* code, in particular DeviceOrientationEvent::requestPermission()
We should probably check if:
DeviceOrientationAndMotionAccessController::shouldAllowAccess()'s
bool mayPrompt = UserGestureIndicator::processingUserGesture(&document);
Is changing to false.
My suspicion is still that too many things might be poking at whatever controls processingUserGesture()
Radar WebKit Bug Importer
<rdar://problem/123284434>
Ashley Gullen
We aren't calling any other API that would consume a user gesture in that touch event - it should be more or less receiving a MessagePort message and then calling DeviceOrientationEvent.requestPermission() in that handler.