opentok-android-sdk-samples
opentok-android-sdk-samples copied to clipboard
com.opentok.android.Camera2VideoCapturer$Camera2Exception: CAMERA_DISABLED (1): validateClientPermissionsLocked:1502: Caller "com.company" cannot open camera "3" from background
Caused by : swithing app foreground to background multiple times getting below crash
com.opentok.android.Camera2VideoCapturer$Camera2Exception: CAMERA_DISABLED (1): validateClientPermissionsLocked:1502: Caller "com.company" (PID 103, UID 255) cannot open camera "3" from background (calling UID 103 proc state 16) at com.opentok.android.Camera2VideoCapturer.initCamera(Unknown Source:101) at com.opentok.android.Camera2VideoCapturer.a(Unknown Source:12) at com.opentok.android.Camera2VideoCapturer.$r8$lambda$EOJ6zJ_KyEal1aLQznxfTJOPcJc(Unknown Source) at com.opentok.android.Camera2VideoCapturer$$ExternalSyntheticLambda3.run(Unknown Source:4) at com.opentok.android.Camera2VideoCapturer$4.onClosed(Unknown Source:44) at android.hardware.camera2.impl.CameraDeviceImpl$5.run(CameraDeviceImpl.java:229) at android.os.Handler.handleCallback(Handler.java:938) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loopOnce(Looper.java:226) at android.os.Looper.loop(Looper.java:313) at android.app.ActivityThread.main(ActivityThread.java:8663) at java.lang.reflect.Method.invoke(Method.java:-2) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:567) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1135)
+1
any updates on this ? :)
Same here. Any updates on this?
Hi 👋,
Is this issue reproducible on the latest version of the SDK? Please advise. Thanks! 🙏
for me this only happens on the newest version
Thanks, @AndreasKarlzzon.
Which models of phone are you able to reproduce this with?
https://jira.vonage.com/browse/OPENTOK-49276
samsung o1s (Galaxy S21 5G), samsung beyond1 (Galaxy S10), samsung x1s (Galaxy S20 5G) and more :)
Just wanted to provide an update. We tried to reproduce on an Samsung Galaxy Z Flip 4 but didn't have any luck.
I'll see if someone has one of the devices listed and try again.
Just wanted to provide an update. We weren't able reproduce the issue on an Samsung Galaxy S10+ either.
I wonder if we're missing a key step. @AndreasKarlzzon can you provide more detailed steps to reproduce please? Thanks!
Just a sample:
- Pixel 6 Pro
- Galaxy S21 5G
- Galaxy A53 5G
- Galaxy A13 5G
- moto g stylus 5G
- Galaxy S9
- Galaxy Note9
- Galaxy Note20 5G
Looks like there is no correlation between the error and device. Android 9, 11, 12, 13
For us, we saw this on any device that has more than 1 back camera and uses the Camera2 capturer, had to roll back from 2.24 to 2.22.3 and include the Huawei patch in our own code
One of my projects has been experiencing this issue since at least SDK version 2.23.0, but I'm quite sure it happened before then as well.
My phone has four cameras, three on the back and one on the front. The cycleCamera()
function switches through these four cameras, but when the last camera is selected and cycleCamera()
is called again, the app crashes with a similar log.
To look into this, I ran the following code on my device:
val manager: CameraManager = getSystemService(CAMERA_SERVICE) as CameraManager
manager.cameraIdList.forEach {
Log.d(
"camera",
"id: $it isBackFacing: ${
(manager.getCameraCharacteristics(it)
.get(CameraCharacteristics.LENS_FACING) == CameraMetadata.LENS_FACING_BACK)
}"
)
}
I get the following result in the logs:
D/camera (13482): id: 0 isBackFacing: true
D/camera (13482): id: 1 isBackFacing: false
D/camera (13482): id: 2 isBackFacing: true
D/camera (13482): id: 3 isBackFacing: true
D/camera (13482): id: 4 isBackFacing: true
D/camera (13482): id: 5 isBackFacing: true
D/camera (13482): id: 6 isBackFacing: true
D/camera (13482): id: 7 isBackFacing: false
So the CameraManager is returning more cameras than there actually are. I then use a (deprecated) function to set the cameraId to an id of a camera that should exist: publisher?.cameraId = 0
and then one that should not exist: publisher?.cameraId = 7
. CameraId 0 works, but CameraId 7 results in a crash.
Logs
E/AndroidRuntime(16771): com.opentok.android.Camera2VideoCapturer$Camera2Exception: CAMERA_ERROR (3): endConfigure:559: Camera 7: Error configuring streams: Function not implemented (-38)
E/AndroidRuntime(16771): at com.opentok.android.Camera2VideoCapturer.doStartCapture(Unknown Source:173)
E/AndroidRuntime(16771): at com.opentok.android.Camera2VideoCapturer.c(Unknown Source:0)
E/AndroidRuntime(16771): at com.opentok.android.Camera2VideoCapturer.$r8$lambda$Ja1sVxV4wLYhzOqCHGFwz3iLgIQ(Unknown Source:0)
E/AndroidRuntime(16771): at com.opentok.android.Camera2VideoCapturer$$ExternalSyntheticLambda0.run(Unknown Source:2)
E/AndroidRuntime(16771): at com.opentok.android.Camera2VideoCapturer$4.onOpened(Unknown Source:40)
E/AndroidRuntime(16771): at android.hardware.camera2.impl.CameraDeviceImpl$1.run(CameraDeviceImpl.java:165)
E/AndroidRuntime(16771): at android.os.Handler.handleCallback(Handler.java:938)
E/AndroidRuntime(16771): at android.os.Handler.dispatchMessage(Handler.java:99)
E/AndroidRuntime(16771): at android.os.Looper.loopOnce(Looper.java:201)
E/AndroidRuntime(16771): at android.os.Looper.loop(Looper.java:288)
E/AndroidRuntime(16771): at android.app.ActivityThread.main(ActivityThread.java:7842)
E/AndroidRuntime(16771): at java.lang.reflect.Method.invoke(Native Method)
E/AndroidRuntime(16771): at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:550)
E/AndroidRuntime(16771): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)
Notice how the first line says "Camera 7: Error configuring streams: Function not implemented". OpenTok/Vonage should implement a handler that takes care of this issue.
I currently "fix" this issue using the following code:
val manager: CameraManager = getSystemService(CAMERA_SERVICE) as CameraManager
val frontCameraId: String? = manager.cameraIdList.first { id: String ->
manager.getCameraCharacteristics(id)
.get(CameraCharacteristics.LENS_FACING) == CameraMetadata.LENS_FACING_FRONT
}
val backCameraId: String? = manager.cameraIdList.first { id: String ->
manager.getCameraCharacteristics(id)
.get(CameraCharacteristics.LENS_FACING) == CameraMetadata.LENS_FACING_BACK
}
binding.buttonSwitchCam.setOnClickListener {
if (mPublisher?.cameraId == frontCameraId?.toInt()) {
backCameraId?.toInt()?.let {
mPublisher?.cameraId = it
}
} else {
frontCameraId?.toInt()?.let {
mPublisher?.cameraId = it
}
}
}
I would like to request OpenTok does not deprecate the getCameraId/setCameraId functionality, but update it to accept strings in stead of integers, as the CameraManager returns camera ids in the form of strings.
Update:
After releasing this code I noticed some crashes. If you use this solution make sure you have the camera permission. Updated code:
val frontCameraIndex: Int = manager.cameraIdList.indexOfFirst { id: String ->
manager.getCameraCharacteristics(id)
.get(CameraCharacteristics.LENS_FACING) == CameraMetadata.LENS_FACING_FRONT
}
val backCameraIndex: Int = manager.cameraIdList.indexOfFirst { id: String ->
manager.getCameraCharacteristics(id)
.get(CameraCharacteristics.LENS_FACING) == CameraMetadata.LENS_FACING_BACK
}
buttonSwitchCam.setOnClickListener {
if (mPublisher?.cameraId == frontCameraIndex) {
if (backCameraIndex != -1) {
mPublisher?.cameraId = backCameraIndex
}
} else {
if (frontCameraIndex != -1) {
mPublisher?.cameraId = frontCameraIndex
}
}
}
This works better with the implementation of Publisher.getCameraId/setCameraId.
Any updates on this?
We started seeing this in Crashlytics after updating to the latest version (2.24.0). The problem seems to be indeed caused by cycling the camera and it happened so far on the following devices (according to Crashlytics): Xiaomi Mi 10 lite Xiaomi Redmi Note 10 Pro Samsung Galaxy S10e Galaxy S20 Galaxy Tab S7 FE
We have started seeing this issue too, I am not sure if we have seen it before 2.24.0. A recent crash happened on Galaxy S21+ 5G running Android 12.
It seems that the latest OpenTok versions don't really play well with devices that have multiple cameras. For example Huawei P30 is broken, but Pixel 4a is fine.
How to reproduce: Use a device with more than 2 cameras. Start a session with camera and then call swapCamera()
to switch to the back camera. Now end session. If you start another session again (without restarting the app process) then the camera view will be black.
This has been a bug for so long - we already had a workaround in the past where we would call swapCamera()
again to switch back to the front camera when you end the call. But on 2.24.0 this doesn't work because of the multiple camera support bug.
So basically we now use a similar code like posted above, we keep a list of front and back cameras IDs. And when you end the call we check if user.cameraId
is an ID from the list of back cameras. If yes then we use user.cameraId = frontCameraIndexes.first()
to switch to the front camera again. This fixes the bug when next sessions have a black camara view. But it's just a horrible hack and workaround around OpenTok issues.
Also - swapCamera()
will iterate over all cameras on the device. So on a Huwaei it will not switch between front and back, it will switch to back normal, back wide, back macro and then front. I think that OpenTok should only switch between the default back and front. You can use user.cameraId
to switch to a specific camera.
Thanks everyone for all your input.
Someone on the team has a Pixel 6, which has multiple cameras. We'll try to reproduce using that. Will keep you posted.
Hi, @v-kpheng I would appreciate if you have any status updates on this.
I work for a large organization that uses OpenTalk and we are suffering from the same issue after using the 2.24.0 version.
Thanks
@fpiresca, sorry for the lack of updates. The "someone" on the team with the Pixel 6 was me and I just came back from vacation.
Issue is still on our sprint. Will provide an update soon.
Thanks for the fast response @v-kpheng I appreciate the support.
Fatal Exception: com.opentok.android.Camera2VideoCapturer$Camera2Exception: CAMERA_DISABLED (1): validateClientPermissionsLocked:1226: Caller "com.android.phoenix" (PID 10042, UID 25578) cannot open camera "0" from background (calling UID 10042 proc state 12).
can any body help
@v-kpheng any updates? We are also seeing this issue in production.
Same here. We have an app in production that is affected by this issue, and we have not come up with a way to workaround it.
Hi @v-kpheng, could you please provide an update on this issue? It's been over a month since you promised an update. :disappointed: We see lots of these crashes happening in our production app, and the number of crash-free sessions has plummeted significantly due to this issue.
@Roman-hub, sorry, progress was stalled because of my vacation and higher priority items. I have bandwidth to look into this now.
Just wanted to share an update. I couldn't reproduce on my Pixel 6. While doing cycleCamera
I noticed that only one of the rear cameras appeared. This is probably why I can't reproduce.
I asked my colleague to try to reproduce again on her Samsung Z Fold 4, which has three physical rear cameras.
Hello @v-kpheng According to our crash data, 90% of crashes are coming from samsung devices and 100% background. Could you please try to reproduce this from Samsung Note. this is critical issue for us. thanks
Fatal Exception: com.opentok.android.Camera2VideoCapturer$Camera2Exception: CAMERA_DISABLED (1): validateClientPermissionsLocked:1299/.../cannot open camera "1" from background
Thanks, @pc-anuruddha. We'll need to try to get our hands on a Samsung Note 🤞.
My colleague tried to reproduce again on her Samsung Z Fold 3 but couldn't, despite it having multiple rear cameras. This was her test method:
- Use "cycleCamera" to iterate through cameras until a rear camera is displayed
- Send app to background and back to foreground multiple times, to try to get it to crash
The app never crashed. She also tried to set it to a different rear camera, but no luck there either.
@v-kpheng Could there be a problem with a session restart? In our app an event can be sent to the signaling channel indicating the need to restart the session. In that case current session is ended, using session.disconnect(), and a new one is started. We don't call cycleCamera() anywhere in our code.