3

I'm debugging why on Android's Chrome browser why no devices are getting listed when I run:

ZoomVideo.getDevices()

Once it hits that line of code, my phone will request permission to use my camera, I press ALLOW permission, and then I see the error in the console right away after:

DOMException: Permission denied

Anyone have any idea what's going on? This is a React frontend application using Zoom's API

user1189352
  • 3,628
  • 12
  • 50
  • 90

2 Answers2

0

just found the answer after opening a bounty...

in Android microphone permissions, "Ask every time" is not enough; you must have it on "Allow only while using the app"

user1189352
  • 3,628
  • 12
  • 50
  • 90
0

Though you found the answer yourself, you asked for a canonical one. So I allow myself to elaborate a bit on the background of your question and solution, as you wanted to know, what's going on. ;-)

One may use the links as starting points for further research in detail.

Use Cases -- Camera, Microphone & Location

Astonishingly the permission Allow only while using the app -- and actually the whole topic -- is not very well elaborated in open sources. Let's start with two cases where this permission is applied. The Techwise guide "How to Allow Chrome Access to Camera and Microphone on Android" mentions the step

  1. Tap on the Camera option and select Allow only while using the app.

Also we'll find a comparable situation described in "Request location access at runtime" at the Android Developers Documentation.

Figure 1. Location-sharing feature that requires foreground location access. The feature is enabled if the user selects Allow only while using the app.

It is no coincidence, that we'll find Allow only while using the app either in a context of camera/microphone or location (let's abbreviate them as CML from now on). The Google Support page "Change app permissions on your Android phone" lists

To change a permission setting, tap it, then choose Allow or Don't allow.

For location, camera, and microphone permissions, you may be able to choose:

  • All the time: For location only. The app can use the permission at any time, even when you’re not using the app.
  • Allow only while using the app: The app can use the permission only when you're using that app.
  • Ask every time: Every time you open the app, it'll ask to use the permission. It can use the permission until you’re done with the app.
  • Don't allow: The app cannot use the permission, even when you’re using the app.

Sensibility demands for Strictness

Earlier you would find also for CML only Allow, Don't Allow, and something like Ask every time, Ask first, Ask to allow or similar. Either one decides beforehand to allow or not, or every time the application is started. So far so easy.

However, it is obvious that CML are sensible, and with Android 10 (API level 29) their usage has become more restrictive, especially in one point -- also to differ between foreground and background services. As we can read in the docs on "Request location permissions: Background location"

On Android 10 (API level 29) and higher, you must declare the ACCESS_BACKGROUND_LOCATION permission in your app's manifest in order to request background location access at runtime. On earlier versions of Android, when your app receives foreground location access, it automatically receives background location access as well.

One may mark the "earlier" here, and remember the "earlier" mentioned above. There's a connection. Also note the keyword "runtime". As the docs say on "Runtime permissions":

Runtime permissions, also known as dangerous permissions, give your app additional access to restricted data or let your app perform restricted actions that more substantially affect the system and other apps.

Therefore the user has to grant such permissions explicitly. The developer shall

not assume that these permissions have been previously granted -- check them and, if needed, request them before each access.

That leads to the well-known permission prompt for the access of storage, contacts, CML, or whatever else sensible -- though CML are seen as particular sensible. Therefore, the CML's permission list implies a hierarchy as follows:

  • Don't allow: Nomen es omen.
  • Ask every time: Reflects only the user's fundamental permission to use the service, given in beforehand at installation time. Won't be enough when a more strict permission is expected like for CML, as this option doesn't differ between foreground and background access.
  • Allow only while using the app: Explicitly grants access to the service in question only in foreground, when the app is used.
  • All the time: For location only. Explicitly allow location service to run not only in foreground, but also in background.

So, although Ask every time can be used to grant access e.g. to storage or contacts, it is not enough where the paradigma is applied, that the usage of a service in foreground or background has to be regarded separately in respect of permissions. Maybe in the future that paradigma will not only apply to CML.

NB: The word "separately" could be misleading. Finally you have three options

  • Don't allow
  • Allow foreground
  • Allow foreground and background

There's no option to get a permission for background without a permission for foreground.

Conclusion

Ask every time has not been enough in your case, because it isn't strict enough for a Camera service since Android 10. Hence you had to grant the stricter permission Allow only while using the app.

Krokomot
  • 3,208
  • 2
  • 4
  • 20