Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Requesting permission shouldn't imply storing it. #93

Closed
alvestrand opened this issue Apr 27, 2016 · 15 comments
Closed

Requesting permission shouldn't imply storing it. #93

alvestrand opened this issue Apr 27, 2016 · 15 comments

Comments

@alvestrand
Copy link
Collaborator

As written, step 9 of the "request permission" algorithm says

"Get a permission storage identifier for permissionDesc.name and the current environment settings object, and create a permission storage entry mapping this identifier to storage."

I believe this should be an UA choice, based on user preferences. Granting permission to use "now" and granting permission to use "permanently" are two different things.

Suggestion: Preface this sentence with "If the user interaction indicated that the user wanted the permission to be permanently stored, get...."

@jan-ivar
Copy link
Member

Before we transmute the text further, can we get a clear statement from its editors about what the intent of the "request a permission" algorithm is? - Confusion seems to abound about what its purpose is.

Is it to elevate the permission level? (from prompt to granted)?
Is it to request (including potentially prompt for) access?

I know Chrome conflates the two (offering no way to obtain camera access without implicitly elevating persistent permissions to 'granted'), but other browsers, like Firefox, do not, and this spec should not.

It's not clear to me that adding some form of expiry to the existing permission states is the right approach, as it only seems to allow this confusion to continue.

@jyasskin
Copy link
Member

I intend "request a permission" to request, including potentially prompt for, access to a capability, or, equivalently, permission to access a capability. I don't intend it to guarantee that the permission is stored. I see it as a mistake in the spec that it's currently too wedded to Chrome's behavior where the permission is always stored.

@jan-ivar
Copy link
Member

@jyasskin when would this algorithm return 'prompt' as a value, and what would that value mean in this context?

@jyasskin
Copy link
Member

jyasskin commented Apr 27, 2016

I'm not sure what the best behavior would be. I can imagine a couple options:

The site calls request({name:"camera", ...}), and the user grants temporary access to a camera

  1. request returns {state: "granted", stream: someMediaStream}. The site has to call query({name:"camera", ...}) to figure out if a future call will prompt.
  2. request returns {state: "prompt", stream: someMediaStream} to convey both the granted permission and the fact that future calls will still prompt.

The site calls request({name:"camera", ...}), and the user closes the prompt without granting or denying it.

  1. request returns {state: "prompt", stream: null} to convey that nothing was granted, but the site can still show another prompt.
  2. request returns {state: "denied", stream: null}. The site has to call query({name:"camera", ...}) to figure out if a future call will prompt or be auto-denied.

Do you have preferences?


For Bluetooth, I have query() and request() always returning "prompt", because request() will always show the chooser even if the site already has access to another device, but I'm not sure that's the right return value.

@jan-ivar
Copy link
Member

@jyasskin The request() API is still controversial as I understand it.

I think my immediate concern is that the editors of Media Capture and Stream spec (which is past last-call) appear to think this (non-consensus) Editor's Draft's _request a permission_ algorithm is something they can normatively call from their getUserMedia algorithm (step 7).

Would the _request a permission_ algorithm return 'prompt' or 'granted' in this case to signify temporary access?

Would anything else be returned from this algorithm to the getUserMedia algorithm (like a stream)?

@jyasskin
Copy link
Member

Yeah, I don't mean to imply that we'll keep the request() function. My use of request() is just a shorthand for calls to the request a permission algorithm. I also don't mean to say that the Permissions spec is or isn't stable enough for Media Capture to depend on it at this point. That's up to your working group with my input that a lot of this is going to change before it settles down, especially anything touching on temporary permissions.

I was trying to say earlier that we don't know whether request a permission will return 'prompt' or 'granted' to signify temporary access. That implies that Media Capture shouldn't rely on this decision, since it might change after you take your CR vote.

Right now, the wording says Media Capture has to make its own decision about which of 'prompt' or 'granted' to return. It needs to do this by defining a (confusingly-named, sorry) permission request algorithm that's in charge of figuring out what to show in the prompt, showing the prompt, and building any specialized return value that might include a MediaStream.

But I think we can have the Permissions spec make the decision between 'prompt' and 'granted' for ephemeral permissions (ones that don't even get remembered as long as a realm), assuming that Media Capture tries to store 'granted'. I just need to know which of the options you want.

@alvestrand
Copy link
Collaborator Author

I think we should define that the "request access" algorithm (my current working name for what's currently called the "request a permission" algorithm) only returns "granted" or "denied", never "prompt".
It's not a query for whether it will prompt or not, it is "I need this access, tell me once you can give me a yes or no answer".

@mounirlamouri
Copy link
Member

Couple of comments:

  • Developers need to know if request() ended up as a no-op. This is the most common outcome of a permission prompt and leaving the promise hanging wouldn't be good.
  • The PermissionStatus returned by request() represent the current state of the permission. If it returns granted but then a call to query() returns prompt, there is an inconsistency that I would call a bug. The spec says that PermissionStatus' value should actually change in that case.
  • How does a permission gets granted now. I can imagine a permission granted for some time, a permission granted for the session but now is something I haven't seen. The concept of a request that only applies at the time when the request is made also sounds meaningless because you couldn't do anything with it. Though, I feel that I might be missing something here.

@alvestrand
Copy link
Collaborator Author

Mounir, to your last comment: that's why we need to separate access from permission.

It's completely reasonable (at least from a design perspective) to say "you have permission to use the camera, here's the MediaStreamTrack originating from the camera, you have it until it ends, if you want another one, ask me again".

@jan-ivar
Copy link
Member

I'd like to propose we change our states to cover temporary permission (which could be reused as return values in the access algorithm to infer temporal and/or one-time access):

'prompt'
'allowed temporarily'
'allowed'
'blocked temporarily'
'blocked'

I.e. add two "temporarily" states, and rename the one-off-sounding "denied" to a more permanent "blocked".

This matches language in a new UX re-design currently being discussed in Firefox. There seems to be value in communicating temporary access to users, so aligning what sites see with this might simplify things.

The exact meaning of "temporary" might be up for discussion, or left up to browsers. For instance, for cameras, temporary access may end once the last obtained camera stream is stopped, at which point reported access reverts to 'prompt'. Also, some browsers may decide to re-prompt for each new stream obtained even in this temporary state (but whenever used as a return value from an access algorithm, 'allowed temporarily' would nonetheless be overloaded to mean that one-off access has been granted).

Similarly, browsers might look at 'blocked temporarily' and/or other criteria to decide whether a particular site should be automatically turned away without prompting the user again within this session or some time period, whereas 'blocked' should probably never be changeable from a site.

In any case, there seems to be some room for innovation and/or open areas for discussion here. Thoughts?

@alvestrand
Copy link
Collaborator Author

What do you mean by "users" here? The app writer, or the browser/app user?
The linked Mozilla bug seems totally irrelevant, unless there's content I'm not allowed to see.

If the app wants to know if permission has been stored permanently after requesting access, it can always do another query() operation. The multiple return values seems like clutter to me.

@jan-ivar
Copy link
Member

By users I mean end-users of the browser, the "user" in "user agent".

See the mockup in the URL field of the bug. Here's a direct link to the relevant page.

@jan-ivar
Copy link
Member

If the app wants to know if permission has been stored permanently after requesting access, it can always do another query() operation. The multiple return values seems like clutter to me.

@alvestrand you seem to disagree with @mounirlamouri 's comment above:

The PermissionStatus returned by request() represent the current state of the permission. If it returns granted but then a call to query() returns prompt, there is an inconsistency that I would call a bug.

These extra states solve this bug.

@jyasskin
Copy link
Member

I believe @alvestrand wants "request access" to use in step 6.7 of http://w3c.github.io/mediacapture-main/getusermedia.html#dom-mediadevices-getusermedia. That's basically the "ask the user" step. It might short-circuit if there's a stored value, but otherwise it does just return "granted" or "denied" and lets the surrounding algorithm figure out what to return to the caller based on that. Telling the surrounding algorithm that it's "temporary" (for either of the two meanings of that word) doesn't help, since it just needs to know whether to give the caller a capability-object.

That said, getUserMedia() actually needs more information from the request than just the "granted" or "denied" answer: it needs to know which MediaStream the user granted access to, and no common "request access" algorithm can possibly return that specialized information. That's why the Permissions editors' draft provides storage management but makes the individual spec define the actual permission prompt.

@jyasskin
Copy link
Member

I'm realizing that this issue is just a duplicate of #86. "Not storing a permission after granting it" is exactly the same as supporting temporary permissions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants