Closed Bug 1616729 Opened 5 years ago Closed 5 years ago

Getting camera video with JSFiddle.net (cross-origin iframe) fails w/NotReadableError on Fenix

Categories

(GeckoView :: Media, defect, P2)

Unspecified
Android
defect

Tracking

(firefox83 fixed)

RESOLVED FIXED
83 Branch
Tracking Status
firefox83 --- fixed

People

(Reporter: jib, Assigned: pehrsons)

References

(Blocks 1 open bug)

Details

Attachments

(3 files)

STRs:

  1. Open https://jsfiddle.net/jib1/r60bzmrs/ in Fenix.
  2. Click "Allow" to use your camera.

Expected result:

  • Camera video appears

Actual result:

  • NotReadableError: Failed to allocate videosource and no camera video.

Workaround:

  1. Open https://fiddle.jshell.net/jib1/r60bzmrs/ (note the different origin) in Fenix.
  2. Click "Allow" to use your camera.

This seems specific to video (microphone appears unaffected) and cross-origin iframes (2nd repro page).

It seems like this might be intentional, as I wouldn't expect permission requests from cross-origin iframes to be a thing we'd want. Smaug, do you know?

Flags: needinfo?(bugs)

Looks like this works fine on desktop (in chrome and firefox), so probably some other issue.

Yeah, given that this works in desktop browsers and mobile Chrome etc. this feels very much like GV or Fenix issue.
And I get the permission popup on Fenix, but even if I let Fenix to use camera, I see the error on the page.
Sounds like some issue in GV/Fenix permission handling.

Flags: needinfo?(bugs)

(In reply to James Willcox (:snorp) (jwillcox@mozilla.com) (he/him) from comment #1)

It seems like this might be intentional, as I wouldn't expect permission requests from cross-origin iframes to be a thing we'd want. Smaug, do you know?

This is governed by feature policy and should very much work when enabled, e.g. with allow="camera; microphone" on the iframe.

Whiteboard: [geckoview:m76]
Rank: 3
Whiteboard: [geckoview:m76]
Whiteboard: [geckoview:m77]
Whiteboard: [geckoview:m77]

This is likely caused by the extra security check in CamerasParent::HasCameraPermission. It's there to prevent camera access from a compromised content process without any camera or mic permission.

The webrtc permission code (which is different on geckoview vs desktop) sets a special kludge permission called "MediaManagerVideo". I suspect the principals aren't matching up somehow, causing this check to fail with NotReadableError.

This has happened before on desktop. See bug 1552379 comment 2. Johann do you recall what the fix entailed?

Flags: needinfo?(jhofmann)

Is GV correctly doing permission delegation? i.e. is it setting the permission for the top level principal or for the third party (should always be the top level)?

Looking at https://searchfox.org/mozilla-central/rev/158bac3df3a1890da55bdb6ffdaf9a7ffc0bfb0a/mobile/android/components/geckoview/GeckoViewPermission.js#174 I don't think it does and that's probably the bug.

Happy to help anyone who wants to pick this up on GV side, it seems like an easy fix. I can also try and get to it but my time is limited.

Flags: needinfo?(jhofmann)

ni myself for fixing this unless someone else gets to it

Flags: needinfo?(jhofmann)

Hi!
I tested the pages https://jsfiddle.net/pehrsons/yrbxrzhq/ and https://jsfiddle.net/jib1/zaw8r956/ on Nightly 200515 (Build #21360611) with Pixel 2 (Android 9) and I get the following error:
FAILED TypeError for width 60: can't access property "getUserMedia", navigator.media.Devices is undefined

Also, on the workaround page from the description https://fiddle.jshell.net/jib1/r60bzmrs/, I get the 404 Error.

:jib Hi! The behavior described in my previous comment is still reproducible on Nightly 200716 (Build #21981809) GV 80.0a1 from 7/16 with Motorola Moto G6 (Android 8).

Now that Fenix is general population, this bug should perhaps get more attention?

This bug is making it hard to repro camera-related bugs on android, since camera doesn't work in fiddles and codepens.

Also, any WebRTC site running in a third-party context would see camera fail over this. I believe at least jit.si has such business customers, even though https://meet.jit.si itself appears to work (I just tested it).

Flags: needinfo?(snorp)

Clearing priority for re-triage

Flags: needinfo?(snorp)
Priority: P2 → --

I had tested this on Nightly 200910 06:07 (Build #2015763059) GV 82.0a1 from 9/10 with Pixel 2 (Android 9):

FAILED TypeError for width 60: can't access property "getUserMedia", navigator.media.Devices is undefined

TypeError: can't access property "getUserMedia" navigator.mediaDevices is undefined

404 That page doesn't exist.

For all these page, I don't receive a permission prompt for camera access, only the error.

QA Whiteboard: [geckoview:m83]
Priority: -- → P2

(In reply to Eliza Balazs from comment #14)

I had tested this on Nightly 200910 06:07 (Build #2015763059) GV 82.0a1 from 9/10 with Pixel 2 (Android 9):

FAILED TypeError for width 60: can't access property "getUserMedia", navigator.media.Devices is undefined

TypeError: can't access property "getUserMedia" navigator.mediaDevices is undefined

FWIW, you get these errors when accessing the fiddles using http://. With https:// the prompts show.

(In reply to Andreas Pehrson [:pehrsons] from comment #16)

(In reply to Eliza Balazs from comment #14)

I had tested this on Nightly 200910 06:07 (Build #2015763059) GV 82.0a1 from 9/10 with Pixel 2 (Android 9):

FAILED TypeError for width 60: can't access property "getUserMedia", navigator.media.Devices is undefined

TypeError: can't access property "getUserMedia" navigator.mediaDevices is undefined

FWIW, you get these errors when accessing the fiddles using http://. With https:// the prompts show.

That is correct. Thank you!
When accessing https://jsfiddle.net/pehrsons/yrbxrzhq/ the prompts show and the error is:

  • FAILED NotReadableError for width 60: Failed to allocate videosource

and when accessing https://jsfiddle.net/jib1/zaw8r956/ the error is:

Tested on Nightly 201002 05:00 (Build #2015767275) GV 83.0a1 from 10/2 with Pixel 2 (Android 9).

I wrote a very simple patch to fix this. But I have to say it's a bit disturbing that no tests cover this at all. I'll put the patches up and if test coverage is wanted I'll leave that to the fenix team.

Assignee: nobody → apehrson
Status: NEW → ASSIGNED

Test-only: https://treeherder.mozilla.org/#/jobs?repo=try&&revision=de96ae781704cc878c33bb5c3ce316309c983879
With patches: https://treeherder.mozilla.org/#/jobs?repo=try&revision=5ccc46eae5c8e3ef06dab123ac0a3e036cea909d

Note that for the test failure, on try I get only:

[task 2020-10-07T13:09:11.796Z] 13:09:11     INFO -  org.mozilla.geckoview.test | Error in testDeviceRecordingEventAudioAndVideoInXOriginIframe(org.mozilla.geckoview.test.MediaDelegateXOriginTest):
[task 2020-10-07T13:09:11.797Z] 13:09:11     INFO -  org.mozilla.geckoview.test | java.lang.AssertionError: stream should have been stopped
[task 2020-10-07T13:09:11.797Z] 13:09:11     INFO -  org.mozilla.geckoview.test | Expected: <true>
[task 2020-10-07T13:09:11.798Z] 13:09:11     INFO -  org.mozilla.geckoview.test |      but: was <false>
...
[task 2020-10-07T13:09:11.804Z] 13:09:11     INFO -  org.mozilla.geckoview.test | INSTRUMENTATION_STATUS: id=AndroidJUnitRunner
[task 2020-10-07T13:09:11.804Z] 13:09:11     INFO -  org.mozilla.geckoview.test | INSTRUMENTATION_STATUS: test=testDeviceRecordingEventAudioAndVideoInXOriginIframe
[task 2020-10-07T13:09:11.805Z] 13:09:11     INFO -  org.mozilla.geckoview.test | INSTRUMENTATION_STATUS: class=org.mozilla.geckoview.test.MediaDelegateXOriginTest
[task 2020-10-07T13:09:11.805Z] 13:09:11     INFO -  org.mozilla.geckoview.test | INSTRUMENTATION_STATUS: stack=java.lang.AssertionError: stream should have been stopped
[task 2020-10-07T13:09:11.805Z] 13:09:11     INFO -  org.mozilla.geckoview.test | Expected: <true>
[task 2020-10-07T13:09:11.805Z] 13:09:11     INFO -  org.mozilla.geckoview.test |      but: was <false>

But locally I get more:

 0:05.54 org.mozilla.geckoview.test There were 3 failures:                                                                                                                                                 
 0:05.54 org.mozilla.geckoview.test 1) testDeviceRecordingEventAudioAndVideoInXOriginIframe(org.mozilla.geckoview.test.MediaDelegateXOriginTest)                                                           
 0:05.54 org.mozilla.geckoview.test java.lang.AssertionError: onRecordingStatusChanged should be called specified number of times                                                                          
 0:05.54 org.mozilla.geckoview.test Expected: <1>                                                                                                                                                          
 0:05.54 org.mozilla.geckoview.test      but: was <0>
...
 0:05.55 org.mozilla.geckoview.test 2) testDeviceRecordingEventAudioAndVideoInXOriginIframe(org.mozilla.geckoview.test.MediaDelegateXOriginTest)
 0:05.55 org.mozilla.geckoview.test java.lang.AssertionError: getUserMedia should have succeeded
 0:05.55 org.mozilla.geckoview.test Expected: "ok"
 0:05.55 org.mozilla.geckoview.test      but: was "NotReadableError: Failed to allocate videosource"
...
 0:05.55 org.mozilla.geckoview.test 3) testDeviceRecordingEventAudioAndVideoInXOriginIframe(org.mozilla.geckoview.test.MediaDelegateXOriginTest)
 0:05.55 org.mozilla.geckoview.test java.lang.AssertionError: stream should have been stopped
 0:05.55 org.mozilla.geckoview.test Expected: <true>
 0:05.55 org.mozilla.geckoview.test      but: was <false>

The NotReadableError: Failed to allocate videosource is what would be useful to me as a developer debugging any issues here.

Yeah unfortunately this is a limitation of the assert method we use, it will continue execution and the last assertion failure is the one reported.

(In reply to Andreas Pehrson [:pehrsons] from comment #18)

I wrote a very simple patch to fix this. But I have to say it's a bit disturbing that no tests cover this at all. I'll put the patches up and if test coverage is wanted I'll leave that to the fenix team.

Expecting the Fenix team that works on Github to write a Gecko test is folly.

The geckoview team then? Whoever owns this code -- fenix is certainly a bigger stakeholder in this code than the media team (me). Sorry, didn't mean to step on any toes.

Flags: needinfo?(jhofmann)
Pushed by pehrsons@gmail.com: https://hg.mozilla.org/integration/autoland/rev/067c5ec03757 Add geckoview-junit test for cross-origin subframe gUM request with allow/no-allow. r=geckoview-reviewers,agi https://hg.mozilla.org/integration/autoland/rev/f74ce923e277 Use the top window's document origin for requesting camera permissions. r=geckoview-reviewers,johannh,agi https://hg.mozilla.org/integration/autoland/rev/2de4c253c7a7 Show top window's document origin to users when requesting media device permissions. r=geckoview-reviewers,johannh,agi
Status: ASSIGNED → RESOLVED
Closed: 5 years ago
Resolution: --- → FIXED
Target Milestone: --- → 83 Branch
Regressions: 1674099

I had tested this issue on Nightly 201029 05:01 (Build #2015772457) GV 84.0a1 from 10/29 with Motorola Moto G6 (Android 9) and when accessing https://jsfiddle.net/pehrsons/yrbxrzhq/ the NotReadableError: Failed to allocate videosource is not displayed anymore but while allowing the prompt the 27th time or before, I get the crash:
https://crash-stats.mozilla.org/report/index/77454dff-8d56-40c3-b5f0-650740201029#tab-details
java.lang.RuntimeException
at org.webrtc.ThreadUtils.invokeAtFrontUninterruptibly(ThreadUtils.java:3)
at org.webrtc.TextureBufferImpl.toI420(TextureBufferImpl.java:1)
at org.webrtc.videoengine.VideoCaptureAndroid.onFrameCaptured(VideoCaptureAndroid.java:2)
at org.webrtc.CameraCapturer$2.onFrameCaptured(CameraCapturer.java:10)
at org.webrtc.Camera2Session$CaptureSessionCallback.lambda$onConfigured$0$Camera2Session$CaptureSessionCallback(Camera2Session.java:16)
at org.webrtc.-$$Lambda$Camera2Session$CaptureSessionCallback$UDvzHNj8-cAJE1WNByx98pxD9vA.onFrame(Unknown Source:2)
at org.webrtc.SurfaceTextureHelper.tryDeliverTextureFrame(SurfaceTextureHelper.java:21)
at org.webrtc.SurfaceTextureHelper.lambda$new$0$SurfaceTextureHelper(SurfaceTextureHelper.java:2)
at org.webrtc.-$$Lambda$SurfaceTextureHelper$7YTfC0byyd0o_zI7mNhfP12Gm0Q.onFrameAvailable(Unknown Source:2)
at android.graphics.SurfaceTexture$1.handleMessage(SurfaceTexture.java:206)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:164)
at android.os.HandlerThread.run(HandlerThread.java:65)

This is not reproducible on https://jsfiddle.net/jib1/zaw8r956/
This issue is not reproducible with Pixel 2 (Android 9).

I had filed a new issue: https://bugzilla.mozilla.org/show_bug.cgi?id=1674099

Moving some media bugs to the new GeckoView::Media component.

Component: General → Media
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: