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


#1

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 CameraManager.open(cameraId:String): 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")
            response.complete(cameraDevice)
        }

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

        override fun onError(cameraDevice: CameraDevice, error: Int) {
            response.completeExceptionally(Exception("Camera onError $cameraDevice $error"))
            cameraDevice.close()
        }
    }, 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.


#2

I’ve answered to your question on StackOverflow: https://stackoverflow.com/questions/48552925/existing-3-function-callback-to-kotlin-coroutines/48562175#48562175


#3

And your answer is exactly it, thank you!