w3c / geolocation-sensor

Geolocation Sensor
https://www.w3.org/TR/geolocation-sensor/
Other
59 stars 21 forks source link

Expose GeolocationSensor to dedicated workers #37

Open anssiko opened 5 years ago

anssiko commented 5 years ago

Reassess whether our identified use cases, in particular the foreground geotracking use cases, would benefit from GeolocationSensor exposed to dedicated and shared workers similarly to NavigatorNetworkInformation and some other APIs. We know this feature can be polyfilled, but that comes with a performance hit (incl. battery) that might negatively impact some important use cases.

We have a F2F resolution to do this but I wanted to resurface the resolution before we update the spec to loop in the wider community and gather new data from recent experiments that have been done meanwhile.

For example, @tomayac has recently experimented with Wake Lock API and geolocation, and as such has a fresh view on requirements for apps that might benefit from this feature.

anssiko commented 5 years ago

Spec-wise, this change seems like a minimal IDL update. Using the same identifier Worker both SharedWorkerGlobalScope and DedicatedWorkerGlobalScope can be addressed in an [Exposed] extended attribute at once:

[Constructor(optional GeolocationSensorOptions options),
 SecureContext,
 Exposed=(Window,Worker)]
interface GeolocationSensor : Sensor {
/ ...
};

And similarly in the Generic Sensor API:

[SecureContext, Exposed=(Window, Worker)]
interface Sensor : EventTarget {
// ...
};

[Constructor(DOMString type, SensorErrorEventInit errorEventInitDict),
 SecureContext, Exposed=(Window, Worker)]
interface SensorErrorEvent : Event {
// ...
};

@reillyeon did I overlook something? I'm thinking what needs to be specced in addition, if any, to ensure UAs can surface possible permission dialogs from within dedicated and shared workers. The integration points are https://w3c.github.io/sensors/#request-sensor-access and https://w3c.github.io/permissions/#request-permission-to-use

Implementation-wise, how much plumbing there is to be done in Chromium to expose Sensor and SensorErrorEvent and in the future some concrete sensors such as this to workers? I'd like to plan this change to be minimally invasive to existing implementation(s).

reillyeon commented 5 years ago

The current language does not make a distinction between requesting access to a sensor in a way that might prompt the user for permission vs. checking that the user has already granted permission or that permission is granted by default. When designing the worker support for WebUSB we settled on allowing a dedicated worker to exercise permissions that the parent frame already had but not to request additional permissions.

I don't think the start() method should implicitly trigger a permission prompt, at least not in a worker context. We should have an explicit requestPermission() method that can be called from a frame context (with a user gesture) before a worker attempts to create a Sensor object.

Putting on my Blink hat, there are implementation complexities which mean that we are more likely to expose sensors only to dedicated workers and not to shared workers. Chrome and Firefox are the only major browsers implementing shared workers and Chrome does not enable them on Android.

kenchris commented 5 years ago

It seems that requestPermission() is an anti-patterns: https://github.com/w3c/payment-handler/issues/246

anssiko commented 5 years ago

Opened a separate issue for requesting permission: https://github.com/w3c/sensors/issues/388

anssiko commented 5 years ago

I submitted two PRs for the IDL update:

Sensor and SensorErrorEvent: https://github.com/w3c/sensors/pull/389 GeolocationSensor https://github.com/w3c/geolocation-sensor/pull/38

reillyeon commented 5 years ago

Looking back at my previous comment and @kenchris's link to the general discussion of requestPermission()-like APIs and I think the key part of my argument above was making it clear to developers what they need to do to make sure that their page has access to a Sensor object.

In the main frame if you call Sensor.start() in response to a user gesture and the page doesn't have sensor permission then the user agent can display a prompt. If you don't have a user gesture then it has to fire an error event to indicate that permission has not been granted. I think of Worker contexts as essentially frame contexts which will never have a user gesture. The trick is to make it easy for developers to figure out when they need to request that permission in the main frame first. The navigator.permissions.query() functions satisfies that requirement. Now the question is, if the page doesn't have permission but the developer actually wants to use a Sensor object in a Worker then does it make sense for them to have to first create that object in the main frame, start it, and then destroy it and start over in the Worker? This is a case where a requestPermission() API seems appropriate.

kenchris commented 5 years ago

I am a bit afraid that a requestPermission feature will lead us with the issues of notifications today, that is that people request it basically at onload time and not close to when the feature is needed. How do you intent to work around that?

reillyeon commented 5 years ago

Notification.requestPermission() function is an outlier compared to most other permission APIs in that it does not require a user gesture even though it is expected to display a prompt to the user.

tomayac commented 5 years ago

I think of Worker contexts as essentially frame contexts which will never have a user gesture. The trick is to make it easy for developers to figure out when they need to request that permission in the main frame first. The navigator.permissions.query() functions satisfies that requirement.

Just thinking out loud here: could there be a Feature Policy that would allow a page to "pass" user gestures to workers/frames? If the page says in its hypothetical Feature Policy user-gesture something like…

Feature-Policy: user-gesture 'self' /worker.js https://example.com/good-iframe.html; […]

…then the worker/frame could directly ask for permission itself.

Now the question is, if the page doesn't have permission but the developer actually wants to use a Sensor object in a Worker then does it make sense for them to have to first create that object in the main frame, start it, and then destroy it and start over in the Worker?

I don't think that's very elegant, there should be something more lightweight, maybe like the admittedly completely vague proposal above.

anssiko commented 5 years ago

Updated the issue title to reflect consensus and spec updates that exposed to dedicated workers the following interfaces:

Sensor and SensorErrorEvent: https://github.com/w3c/sensors/pull/389 GeolocationSensor https://github.com/w3c/geolocation-sensor/pull/38

reillyeon commented 5 years ago

I think of Worker contexts as essentially frame contexts which will never have a user gesture. The trick is to make it easy for developers to figure out when they need to request that permission in the main frame first. The navigator.permissions.query() functions satisfies that requirement.

Just thinking out loud here: could there be a Feature Policy that would allow a page to "pass" user gestures to workers/frames? If the page says in its hypothetical Feature Policy user-gesture something like…

Feature-Policy: user-gesture 'self' /worker.js https://example.com/good-iframe.html; […]

…then the worker/frame could directly ask for permission itself.

User activation transfer could provide a mechanism for requesting permissions from workers in the context of a user gesture in the frame.

Now the question is, if the page doesn't have permission but the developer actually wants to use a Sensor object in a Worker then does it make sense for them to have to first create that object in the main frame, start it, and then destroy it and start over in the Worker?

I don't think that's very elegant, there should be something more lightweight, maybe like the admittedly completely vague proposal above.

I should have made it clear that was a strawman proposal. I think it's pretty inelegant as well. Transfering user activations into a worker seems like the right long-term solution but I'm not convinced that a requestPermission() method that requires a user gesture is much different.

tomayac commented 5 years ago

User activation transfer could provide a mechanism for requesting permissions from workers in the context of a user gesture in the frame.

🎉 This looks exactly like it's providing the functionality that I was envisioning, we don't even need a feature policy, as both the page and the iframe (or worker in the concrete case of this issue) need to agree on the message (but it might still be nice to have one). I have subscribed myself to https://github.com/whatwg/html/pull/4369 to see how it ends.