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

Clarify when the application can retry getUserMedia after it returns "InvalidStateError" due to the window not being in focus #763

Closed
q-alex-zhao opened this issue Jan 13, 2021 · 5 comments

Comments

@q-alex-zhao
Copy link

The media capture spec says:

If the relevant settings object's responsible document is NOT fully active, return a promise rejected with a DOMException object whose name attribute has the value "InvalidStateError".

From whatwg/html#6211, the internal logic for the window being visible and focused would not be exposed to the application. So I think the application should not depend on document.hasFocus() returning true to assume it's good to call getUserMedia to begin with; it should always just call getUserMedia and inspect the result.

My naive question is when the application may retry getUserMedia after receiving this "InvalidStateError", e.g. for showing a preview video before joining a meeting. Just periodically?

@youennf
Copy link
Contributor

youennf commented Jan 13, 2021

We would like to be able to add user gesture restriction to call getUserMedia, like we did for getDisplayMedia.
My advice for web developers would be to call getUserMedia based on a user action like clicking on a button.

@q-alex-zhao
Copy link
Author

Thanks for the suggestion. Some followup questions:

Assuming the user gesture requirement change refers to w3c/mediacapture-extensions#11 and the definition of user gesture refers to transient activation in the getDisplayMedia spec:

When the getDisplayMedia() method is called, the User Agent MUST run the following steps:

  1. If the relevant global object of this does not have transient activation, return a promise rejected with a DOMException object whose name attribute has the value InvalidStateError.

The specific scenario I'm thinking about is this:

  1. the user is using a calendaring app for managing meeting schedules
  2. the user clicks on a "join meeting" button in the calendaring app
  3. this opens up a new window or tab loading the meetings app
    a. does this new window or tab satisfy the transient activation criteria? my read of the spec is that it does not, but I feel it should.
  4. before the meetings app code is downloaded / executed, the user switches to a different window for something else
  5. the meeting app normally would auto-open the camera to show a preview, but now it would fail because, I think, it does not satisfy the "window visible and in focus" criteria
  6. the user notices that the meeting window has some content showing up, and switches back to the meeting window
    a. if the transient activation criteria was satisfied before, would this invalidate it since the transient activation duration is likely to have passed?
    b. would it be reasonable for the application to want to retry getUserMedia, if it knows now the "window visible and in focus" criteria has been satisfied? instead of showing blanks and waiting for the user to click a button...

@jan-ivar
Copy link
Member

jan-ivar commented Jan 14, 2021

@q-alex-zhao I think there's some confusion. Not having focus never produces InvalidStateError.

The media capture spec says:

If the relevant settings object's responsible document is NOT fully active, return a promise rejected with a DOMException object whose name attribute has the value "InvalidStateError".

This sentence is not about focus, but about calling getUserMedia() in a discarded browsing context.

@jan-ivar
Copy link
Member

Instead, the relevant language for focus is in getUserMedia: "The User Agent MUST wait to proceed to the next step until the relevant settings object's responsible document is fully active and has focus." modulo #752

@q-alex-zhao
Copy link
Author

Ah sorry about my confusion. The getUserMedia promise would just not resolve until the focus requirement has been met. I think the application can handle this by showing a "camera is starting" screen, for example. This makes sense. Thanks.

The only drawback I can think of is that the application would not be able to separate the "user time" spent during the waiting for focus period, from the "system time" from actually doing the work opening the device, which the application may want to aggregate as part of product health metrics. But on the other hand getUserMedia may be waiting on the permissions prompt... So probably it's best to just not time it when permission prompting is involved or the application is without focus...

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

3 participants