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
Reported 2024-02-19 06:18:39 PST
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
Marcos Caceres
Comment 1 2024-02-19 18:40:20 PST
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
Comment 2 2024-02-19 18:45:42 PST
*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
Comment 3 2024-02-19 18:46:25 PST
Ashley Gullen
Comment 4 2024-02-20 05:33:05 PST
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.
Note You need to log in before you can comment on or make changes to this bug.