Closed alvestrand closed 3 years ago
Hmm, the first iteration of the spec had request(sequence<PermissionDescriptor> or PermissionDescriptior)
but it made the return type a bit hard to handle (ie. Promise<PermissionStatus>
or Promise<sequence<PermissionStatus>>
) so I planned to have a requestAll()
and @jyasskin removed the union as an argument.
@jyasskin any objection with me adding requestAll()
?
Note that I'm effectively requesting request(sequence<sequence<PermissionDescriptor>>)
with a return type of Promise<sequence<PermissionsStatus>>
.... ie the query has one more level of sequence than the response....
No objection to requestAll()
. I removed request(sequence<>)
because it needed some fixing in the the spec that I didn't want to do right then, and it isn't what Chrome implemented, but I'm not fundamentally opposed to it either.
Personally I kinda like @alvestrand's option 1, where the browser collects up all the request()
calls made within a single turn and shows them in a sensible UI, but I do see that this might be hard to predict for developers.
On request(sequence<sequence<PermissionDescriptor>>)
-> Promise<sequence<PermissionsStatus>>
, I'd imagined that as a group of request({name: 'camera', options: [option1, option2, ...]})
. I see that getUserMedia
may have interacting preferences for the camera and mic, but I'm worried about how we specify that in a generic request()
API, and how the UI should look for arbitrary combinations of these things. Maybe for individual interacting things, we need to keep some separate request APIs? (This may reinforce #83.)
I think maybe we should settle on #83 before adding this?
Regarding requestAll()
and Promise.all(requests)
, I would be in favour of a clear semantic way that reflects clear intentions. For example, Chrome will require you to make decisions on all permissions if it merges them in the same prompt which can lead to worse outcome for the website.
@mounirlamouri so I take it you're in favor of requestAll, then?
Perhaps the request<sequence<sequence<PermissionDescriptor>>>
, perhaps we should call that one requestOneFromEachSetOfAlternatives
? Then request()
and requestAll()
can be defined in terms of this?
(request(foo)
is the same as requestOneFromEachSetOfAlternatives([[foo]])
, requestAll([foo, bar])
is the same as requestOneFromEachSetOfAlternatives([[foo], [bar]])
?
I don't care so much what the JS API is as long as the underlying "request access" mechanism allows the full flexibility.
To me, requestAll
is a good example of why elevating permission requests as its own API is a bad idea (https://github.com/w3c/permissions/issues/83).
To quote the blog I credit with how web permissions today are modeled:
introducing Android-like bundling of permissions with "up front" permission grants would be a mistake.
requestAll
would seem to take us there, and it does not have my vote.
First of all, Android moved out of this system. Second of all, the problem with it is that Android used to (and still does for some apps) require the user to accept the permissions in order to install the applications. This means that users would be incentivized to say yes and overlook a couple of dodgy permissions.
Obviously, there is no equivalent to this system on the Web and adding request()
or requestAll()
isn't actually pushing in that direction. It's just streamlining something that web apps have been doing for a while: asking for permissions. You can already implement request()
for roughly all the web exposed API. requestAll()
is simply a way to define multiple permissions to be related. For example, a website requiring geolocation and notifications to work properly will not have to show two prompts. It's better for the user.
If your general concern is that websites would use this to prevent users access to the content unless the permissions are granted they can already do that. Any video chat app will not allow you to start using it unless you granted them at least mic access because you would have a broken experience otherwise. Will streamlining the methods make it more likely that websites will abuse it? Maybe. I don't know. Though, I don't think we should design based on this.
What is the point of request
and requestAll
if not to untangle permission from existing resource acquisition APIs? That at it's core seems to go against the web permission model we've been building so far, where permission is a question between the user agent and its user, buried in existing resource request APIs, which work fine, and seems to have been successful so far in giving us a web that is forgiving and unlike Android.
If we make something easier to do, then more people will do it.
I also haven't heard a clear statement about what behavior proponents want out of request
and requestAll
. They either allow sites to ask for permission sooner than they need, and in bulk, in which case it is streamlining bad behavior, or it doesn't, in which case it doesn't seem to add anything. Which is it?
@jan-ivar Please try not to derail issues. The topic you're talking about is in #83.
Is the expectation that UX would be built to merge all possible combinations of requests? Laterally chasing generality leads to discovering problems no-one cares about in my experience. I'd like to point out of that getUserMedia
already handles exactly the combination we care about: camera + microphone. It also takes the right arguments and returns the right result, and has the advantage of specific documentation. A benefit of context.
Also, I can't tell whether this issue is about an algorithm for other specs to call, a new API for sites to call, or both.
I would prefer option 1 unless this is intended to be a sort of "atomic" permission request: give my app all these permissions, or give me none of them. That seems like the semantic intent of "requestAll". Otherwise option 1's individual requests, with the browser maintaining UI flexibility for how to present them (separate prompts, dialog with checkboxes, etc.), makes the most sense to me.
@domenic, the issue with the first option is that the UA will have to do some magic behind the hood in order to combine requests coming together. If the spec recommends to combine requests with Promise.all()
, it will force UAs to combine requests coming in the same event loop as in request(); stuff(); request();
. I'm not sure if we want to enforce that kind of magic and likely sometimes unexpected behaviour. Every call should have a reliable outcome and depending on whether a call was made just before I believe breaks this rule. I think it is important to give some control of the UX to the website.
If we do the "combining" thing, I would expect
request(foo); request(camera); request(bar); request(microphone)
to result in 3 simultaneous popups: foo, bar and (camera+microphone), becaue the camera+microphone is the only one that people will write special code for.
I think that's "not too bad"; the WEBRTC spec already has language saying that if one does
getusermedia(camera1); getusermedia(camera2)
the prompts should be combined if possible.
User agents already need to implement combining and/or stacking given the existing APIs. So I'm not sure why we need a new API for that given that we can't simplify the existing situation.
I recommend focusing on modeling the existing world first, before adding more APIs.
Yes, I don't think magic is pejorative here. User interface and presentation is precisely where we want browsers to have maximum flexibility to perform "magic" and improve, without being overly constrained by API surface.
Closing per #83
(People interested in the original proposal ["multiple things need to be asked for in one UI operation"] probably want to track https://github.com/w3c/permissions/issues/191 instead.)
When requesting permission, multiple things need to be asked for in one UI operation - the most common combination in MediaCapture being camera and microphone. There may be multiple suitable options, and the caller may have a preferred ranking.
Two solutions:
1) Combine multiple concurrent permission calls with promise.All, and state that the UI is responsible for presenting multiple requests as one request to the user. This seems complex and non-obvious.
2) Pass multiple lists of permissions as an argument to the "request permission" algorithm, with the assumption that the request succeeds only if one item is successful from each list.