Closed Bug 1195654 Opened 10 years ago Closed 9 years ago

getUserMedia doesn't work when browser window is not focused

Categories

(Firefox :: Site Permissions, defect, P2)

40 Branch
All
Windows 8
defect

Tracking

()

RESOLVED INVALID

People

(Reporter: Marina_Kamayeva, Unassigned)

References

Details

(Keywords: html5)

User Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.155 Safari/537.36 Steps to reproduce: We see the issue with initiating getUserMedia when browser window is not focused and user gave all permissions to access to camera and mic before access to media devices. When triggered getUserMedia and browser isn't focused no callback is called (neither success nor error). When browser window receive focus code continue working, and call callback. For us it looks like an issue. Is this a bug? Are there any ways to avoid such a behavior? EXAMPLE: The similar issue with access to camera we can see at demo chat: https://apprtc.appspot.com/r/700337710 1)Open site first time, allow camera and mic "always". And observe picture from camera. 2)Open again and try to remove focus from browser window before page loaded. Actual results: no video shown Expected results: browser should show video from camera
Component: Untriaged → Device Permissions
Keywords: html5
OS: Unspecified → Windows 8
Priority: -- → P3
Hardware: Unspecified → All
Priority: P3 → P2
Hi, maybe there is any progress or information on this issue?
Severity: normal → major
I believe this as as designed currently, to avoid sites with permanent permission from starting recording when they're not focused/visible. This is similar to the way browsers block certain operations (window opens, etc) unless directly tied to user invocation/clicking. We are redoing the getUserMedia-invoked UI, so if there's a good argument for allowing it (or some other action, like asking the user when non-focused, even though normally a site that has been given "Allow Always" would be able to start capture without user intervention). You should indicate why this is an important problem for your use-case
Flags: needinfo?(florian)
Flags: needinfo?(Marina_Kamayeva)
Background for this would be a website that tests WebRTC on the users browser. As the tests are extensive the user may want to put the browser in the background or do something else while the tests are being run. The tests release permissions after each test to start clean for the next test.
I think it's little bit different that block opening new window, cause to get stream you need manually in popup for first time decide to allow always/once/decline, and for example if I trust site, and pressed for example "always allow", why it need to be blocked if browser not focused? Popup that ask for permission to use media devices is a blocker you described, and it doesn't allow to get stream without user allow this.
The reason is that having a site start recording you when in the background is typically not expected by the user (and not invoked by the user), and thus surprising and a potential serious leak of privacy (i.e. social-engineer someone into giving "Always Allow" on you "Instagram-ish" site, then use that stored permission to record people's conversations). It helps that we now have an always-visible indicator at the top of the screen, so users can notice a mic is active (mics rarely have activity lights, and not all cameras). The issue can be revisited, but would definitely need a thorough look at the privacy and UX aspects (will users understand the appear-from-nowhere top-of-screen notification means something started recording them?)
For real-time communication it's a kind of blocker - absent of reaction at background state. Privacy is important, but in this case it stops "real-time" opportunities. Maybe it's possible to consider not blocking getUserMedia for some kind of "white-list"? Together with possibility to add site to "trusted zone" with such a permission.
Flags: needinfo?(Marina_Kamayeva)
(In reply to Randell Jesup [:jesup] from comment #2) > I believe this as as designed currently, to avoid sites with permanent > permission from starting recording when they're not focused/visible. This > is similar to the way browsers block certain operations (window opens, etc) > unless directly tied to user invocation/clicking. Indeed. Unless I missed something, the only use case that has been given here is automated testing. Someone who intends to run automated WebRTC tests for a while can use a dedicated test profile and set media.navigator.permission.disabled to true in about:config.
Flags: needinfo?(florian)
Hi! I want to raise this question, because I have an example when such behavior looks like a bug from user's side. We're developing video/audio conferences where users can also switch on screenshare. If the user share screen or application, the browser is not in focus in most cases. We have a feature that other users can stop his screenshare and the user gets a notification about that. But if Firefox isn't in focus, getUserMedia doesn't call callback. Moreover we have timeout waiting for answer and when it expires error appears. Please take into consideration this case. I think if Firefox allows to call getUserMedia for sites in white list, it will not affect users privacy (in addition Firefox has a visible indicator).
(In reply to Alexandra Govorkova from comment #9) > I think if Firefox allows to call > getUserMedia for sites in white list, it will not affect users privacy (in > addition Firefox has a visible indicator). We are working on removing the screensharing whitelist (if this is the whitelist you are referring to). Starting a video stream when the user may not notice would definitely affect privacy.
Status: UNCONFIRMED → RESOLVED
Closed: 9 years ago
Resolution: --- → INVALID
It is very important in a communications environment to allow media to be fetched at any point in time (with permission of course). For example, this issue still causes problems in the following real-world scenario: Two Firefox windows are open - One "call-control or CRM panel" and one "telephony panel". If a call is initiated from the "call-control or CRM panel", and an out of band signal is used to start a call in the "telephony panel", then the lack of focus on the "telephony panel" means that getUserMedia will hang. IMHO There are 3 arguments for fixing this bug. 1) The browser has already asked for permission to access media, and it has been granted. This is enough for other browsers. Why does Firefox believe their mechanism is preferable? (Serious question, I am interested!) 2) The getUserMedia callback is never called. If Firefox is denying permission, then at least fail/callback properly so the user knows that Firefox is blocking them, and the application author has a recovery mechanism eg. Notify("Please give me focus!"). 3) A "bad actor" can work around this restriction by opening the media stream immediately while the window has focus and never closing it. A "good actor" wants to leave media closed until necessary. The current Firefox behaviour favours the "bad actor" but not the "good actor".
(In reply to Steve Davies from comment #11) > 1) The browser has already asked for permission to access media, and it has > been granted. This is enough for other browsers. Why does Firefox believe > their mechanism is preferable? (Serious question, I am interested!) If a background tab or window starts eavesdropping the user without the user having any way to notice, we have a serious privacy issue. The permission has been granted by the user for a site to use the device at a time when the user was looking at the website. Selecting "Always allow" when granting the permission means the user doesn't want to see such prompts anymore for this website, it doesn't mean the site is allowed to use the device at any time in the future in cases where a prompt couldn't be displayed. The subset of this bug that would be valid in my opinion is the case when the Firefox window with the getUserMedia request is visible (but not focused). But I'm not aware of a straight forward way to verify that the Firefox window isn't covered by another window. > 2) The getUserMedia callback is never called. If Firefox is denying > permission, then at least fail/callback properly so the user knows that > Firefox is blocking them The callback isn't called because the request hasn't been evaluated yet. Firefox isn't denying access, and will actually be granting access as soon as the window is focused and the tab is selected. > 3) A "bad actor" can work around this restriction by opening the media > stream immediately while the window has focus and never closing it. In this case the sharing indicator will be visible to the user, so the user will be careful about what she says.
Thanks Florian for taking the time to provide some useful feedback. Sadly the response does not address real-world use cases. The fact that this bugzilla entry exists, and is a duplicate of another similar entry indicates that there is a desire to change the current behaviour in Firefox. The current Firefox behaviour is what is having bugs raised on it, suggesting that perhaps something needs to change? I also think your responses are a little bit inconsistent. In 3) you are happy that the sharing indicator is enough to indicate a bad actor, but in 1) and 2) you are happy to indefinitely block legitimate getUserMedia() calls, instead of relying on the sharing indicator for a page that already has permission. IMHO This feels like a double standard, where things are still more favourable for the "bad actor". Perhaps the issue is not really that you do not want to provide media, it is that you are allowing the promise to block. It would (perhaps) be better if you allowed the streams to be resolved correctly, but in a 'muted' mode, which is indicated by (and can be corrected from) the sharing indicator. Sadly at present, for our apps we can only suggest that our users run Chrome and our Chrome plugin - Now that our plugin can run cross-browser, it will do everything except WebRTC in Firefox, which is not a story we want to tell, and I'm sure not a story that Firefox are happy with - Surely there must be a compromise that allows for applications of this nature since they are becoming so much more commonplace?
(In reply to Steve Davies from comment #13) > I also think your responses are a little bit inconsistent. In 3) you are > happy that the sharing indicator is enough to indicate a bad actor, but in > 1) and 2) you are happy to indefinitely block legitimate getUserMedia() > calls You aren't defining "bad actor" or "legitimate calls" here. All I'm talking about is informing (and protecting) users of privacy risks. Your last paragraph confuses me, if by "plugin" you mean add-on, then add-ons are privileged and can use devices without requesting user permission in the first place.
(In reply to Florian Quèze [:florian] [:flo] from comment #14) > You aren't defining "bad actor" or "legitimate calls" here. All I'm talking > about is informing (and protecting) users of privacy risks. > > Your last paragraph confuses me, if by "plugin" you mean add-on, then > add-ons are privileged and can use devices without requesting user > permission in the first place. Apologies. I'll try and clarify. A "bad actor" was defined in comment #11 as software that will opportunistically grab the media while the window has focus, and then keep it open indefinitely as a spying mechanism. This behaviour will work-around the getUserMedia() blocking protection, but is as you said revealed by the sharing indicator. A "legitimate call" is any call to getUserMedia() that the user will find acceptable because they have granted permission to an application that they know they are running. eg. I am running a Firefox based softphone in a minimised window, and want to start a WebRTC negotiation (which currently requires a media stream). Surely it is safe to allow getUserMedia() as long as you then display the sharing indicator? Yes, by "plugin" I mean Chrome extension or Firefox add-on. I accept that the add-on has elevated privileges, but the add-on may not be executing the getUserMedia() call. Can the add-on grant the permission to another window if it wants? eg. A Web-CRM product is running an add-on to allow click-to-dial requests. The click-to-dial makes an out of band call to trigger a Firefox softphone to dial, which requires getUserMedia in a window not controlled by the add-on.
(In reply to Steve Davies from comment #15) > an application that they know they are running. This is the difficult part. How can Firefox know that you know you are running your minimized softphone, and haven't just forgotten a window opened 3 days ago?
:) Clearly a browser cannot know that you have not forgotten the minimised window, but equally I run my Chrome softphone for several weeks on purpose, and I want to be able to forget it! If you have forgotten your softphone is running, and it connects your audio, then it is still an authorised application connecting audio based on a user request (even if it is from another window via an authorised command channel) If you are not happy for that behaviour, then there is the existing browser feature where you tell the browser to "ask every time" by not granting permanent permission. Note 1: As an experiment, I set my browser to do "ask every time", and I notice that if you do not have focus, it does not even try to ask for permission, so you have no way to know that you need to grant permission :( IMHO This current behaviour is preventing some very commonplace WebRTC use-cases in Firefox. Note 2: On a Mac, the sharing indicator is so small as to be almost invisible, so it not useful defence against someone spying with your mic/camera. The best solution to that is to not grant permanent access to your camera to an un-trusted website or application.
(In reply to Steve Davies from comment #17) > notice that if you do not have focus, it does not even try to ask for > permission, so you have no way to know that you need to grant permission :( The Notifications API may cover this use case: https://developer.mozilla.org/en-US/docs/Web/API/Notifications_API/Using_the_Notifications_API
(In reply to Florian Quèze [:florian] [:flo] from comment #18) > (In reply to Steve Davies from comment #17) > > > notice that if you do not have focus, it does not even try to ask for > > permission, so you have no way to know that you need to grant permission :( > > The Notifications API may cover this use case: > https://developer.mozilla.org/en-US/docs/Web/API/Notifications_API/ > Using_the_Notifications_API How would you know to send a Notification for a getUserMedia() that blocks if you do not have permission, but send a notification if you do have permission? I guess you could use a short timeout, but that breaks if the user does not click "allow" quickly enough. We do use the Notification API for inbound calls, and that works well (You need to confirm an inbound call anyway, so focus is a natural part of that process) An outbound call is already initiated by a user-event, so it would be a bit strange to have a notification that you clicked something in order to focus a window in order to get to your media :). Also, if you don't do all of these clicks, your getUserMedia() might "block until tomorrow" when you do focus the window, and your app can suddenly get some media that it no-longer needs from a getUserMedia() call that it cannot cancel or unblock.
If you do have a user action right before you request media, why can't you request media from the window where there has been the user event?
(In reply to Florian Quèze [:florian] [:flo] from comment #20) > If you do have a user action right before you request media, why can't you > request media from the window where there has been the user event? The user action may be in another window, or even another application entirely - We've tested this by having the event triggered in Firefox but causing a call in a Chrome soft-phone for example. It is really cool, but sadly we cannot swap Chrome and Firefox because of this restriction. Also, requesting the media from the window with the user event does not necessarily mean it can be passed to the relevant window or context. I do not believe there is a cross-browser way to serialise and transmit a media stream object? Fundamentally the issue here is of security. Firefox is trying to act securely (a good thing), but is responding to a perceived threat in a manner which I have never seen sanctioned before - By blocking the request you are simply deferring the issue to an "unspecified" later time, when the user has no further say in the event (they already granted permission after all), and by blocking you are preventing the flexibility of programmatic handling of this perceived security threat. Many (most?) of your comments in this thread above have been attempts to work-around the issue. I cannot personally see an upside to the current (unique to Firefox) mechanism, and the fact that you are offering workarounds to it suggests that there really is something wrong that is trying to be worked-around. Is there a forum where the question can be presented to a wider audience within the Firefox community rather than on a closed bug report? If I am wrong I am OK with being told that, but I know I am not alone in this opinion so would like to see it discussed more fully?
(In reply to Steve Davies from comment #21) > Is there a forum where the question can be presented to a wider audience > within the Firefox community rather than on a closed bug report? The mozilla-dev-media@lists.mozilla.org mailing list would be the most relevant place, but I don't see which part of this hasn't fully been discussed yet.
(In reply to Florian Quèze [:florian] [:flo] from comment #22) > > The mozilla-dev-media@lists.mozilla.org mailing list would be the most > relevant place, but I don't see which part of this hasn't fully been > discussed yet. OK, I'll go dog into the archives for any previous conversations in case it helps put this into context.
Context is in bug 1000253.
Ah, thank you for the additional context - I see that there are many posters on that bug who agree with me and my colleagues and who were trying to prevent the current behaviour from being added in the first place. That does also bring up the distinction between TAB and WINDOW. bug 1000253 is referring to background TABS. In Chrome a non-selected TAB will still be allowed to getUserMedia() without being blocked, but the A/V media streams are silent/black until the tab comes to the foreground, and are muted/blacked again if the TAB is sent into the background. For a WINDOW there is no such restriction.
What I would still like to see is a justification for the delaying of a security issue until some possibly accidental focus event fires, at which point no user interaction is required for the media to be handed over, by which time it may no-longer be desirable/safe/appropriate. Reading the W3C definition of getUserMedia here: https://www.w3.org/TR/mediacapture-streams/#methods-5 There is a very well defined sequence of events that includes: "Optionally, e.g., based on a previously-established user preference, for security reasons, or due to platform limitations, jump to the step labelled Permission Failure below." Permission failure then requires that a reject be sent, not that the Promise is left indefinitely unresolved as Firefox is currently doing.

Release Note Request Current Release (Firefox 81.0.2)

My Question is, if this will be fixed or if it is supposed to work like that?

relnote-firefox: --- → ?

Permission failure then requires that a reject be sent, not that the Promise
is left indefinitely unresolved as Firefox is currently doing.

Agreed

Firefox Autoplay can be used to bybass the Policy:
Autoplay is blocked by default (about:preferences). When changing the default to allow for all websites, or specific websites, Firefox will be able to play sounds on non-active Tabs / Windows, if the Audio is played from a Whitelisted website.

It looks like the Autplay functionality only count for Audio, but not WebRTC and SIP/Webrtc Session. It looks like it is still not possible to bypass the strict policy with enabled Autoplay for WebRTC Sessions.

You need to log in before you can comment on or make changes to this bug.