Converting a callback to a suspend fun (so I can chain it)


The Android camera2 classes use a lot of callbacks like CameraDevice.StateCallback, which is fine, but I’d like to take the default path and make it a nice “chainable” series of functions that blocked as much as necessary. I was hoping coroutines would help. Something like

/** Wraps the typical openCamera with a optimistic await path */
suspend fun CameraDevice {
    val response = CompletableDeferred<CameraDevice>() // I don't think I'm doing this part right!
    this.openCamera(cameraId, object : CameraDevice.StateCallback() {
        override fun onOpened(cameraDevice: CameraDevice) {
            println("camera onOpened $cameraDevice")

        override fun onDisconnected(cameraDevice: CameraDevice) {
            response.completeExceptionally(Exception("Camera onDisconnected $cameraDevice"))

        override fun onError(cameraDevice: CameraDevice, error: Int) {
            response.completeExceptionally(Exception("Camera onError $cameraDevice $error"))
    }, null)
    return response.await()

But this crashes the app with no errors in the log. :frowning: which makes me think maybe I’m not understanding how to use CompletableDeferred with a “suspend fun” quite right.


I’ve answered to your question on StackOverflow:


And your answer is exactly it, thank you!